C프로그래밍 3강 - 입출력 함수와 연산자(1)
프로그램과 함수, 표준 입력과 표준 출력의 의미를 이해하고 형식화 입출력 함수인 printf와 scanf의 사용법을 학습한다. 자료형별 변환기호와 출력 양식 편집 방법을 익힌 뒤 getchar, putchar, gets, puts의 차이를 정리한다.
1. 함수와 표준 입출력
함수의 개념
함수(function)는 특정 작업 또는 기능을 수행하도록 설계한 코드 블록이다. 함수는 필요한 데이터를 받아 정해진 처리를 수행하고 결과를 만들 수 있다. C 프로그램의 main도 함수이며 프로그램 실행의 출발점 역할을 한다.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[])
{
printf("Hello, %s!\n", argv[1]);
return EXIT_SUCCESS;
}
이 프로그램을 hello KNOU처럼 실행하면 명령행에서 전달된 KNOU를 사용하여 Hello, KNOU!를 출력한다. 함수가 입력 데이터를 받아 처리 결과를 만드는 기본 구조를 보여 주는 예이다.
표준 입력과 표준 출력
표준 입출력(standard input/output)은 프로그램이 사용자와 데이터를 주고받는 기본적인 입력 장치와 출력 장치를 뜻한다. 표준 입력은 stdin, 표준 출력은 stdout으로 표현하며, 데이터는 문자 시퀀스의 형태로 전달된다.
| 구분 | 스트림 | 대표 함수 |
|---|---|---|
| 표준 입력 | stdin | scanf(), getchar(), gets() |
| 표준 출력 | stdout | printf(), putchar(), puts() |
표준 입출력에서 오가는 데이터의 기본 형태는 문자 시퀀스이다. 형식화 입출력 함수는 이 문자 표현과 C 자료형의 값 사이를 정해진 양식에 따라 변환한다.
2. printf 함수의 구조
printf의 용도와 형식
printf() 함수는 여러 종류의 자료를 지정된 양식으로 콘솔 화면에 출력한다. 출력할 내용만 문자열로 지정할 수도 있고, 변수·계산식·함수 호출의 결과를 양식에 맞춰 문자열로 변환하여 함께 출력할 수도 있다.
printf("출력양식");
printf("출력양식", 수식1, 수식2, ...);
출력양식은 문자열로 작성한다. 뒤에 수식이 이어지면 출력양식 안에 %로 시작하는 양식 변환기호를 넣어 각 값을 어떤 형식으로 변환할지 지시한다. 변환기호의 순서와 수식의 순서 및 자료형이 서로 맞아야 한다.
char c = 'A';
int i = 10, j = 20, k = 30;
printf("'%c'의 ASCII 코드값은 %d\n", c, c);
printf("i=%d, j=%d, k=%d\n", i, j, k);
같은 변수 c를 %c로 출력하면 문자 A가 되고 %d로 출력하면 ASCII 코드값 65가 된다. 값 자체뿐 아니라 어떤 변환기호를 적용하는지에 따라 화면에 나타나는 형식이 달라진다.
3. printf의 자료형별 변환기호
정수 출력
| 변환기호 | 출력 형식 |
|---|---|
%d | 부호 있는 10진 정수 |
%u | 부호 없는 10진 정수 |
%o | 부호 없는 8진수 |
%x, %X | 부호 없는 16진수, 각각 영문 소문자와 대문자 사용 |
변환기호 앞에 h를 추가하면 short int, l을 추가하면 long, ll을 추가하면 long long에 대응한다. 예를 들어 %hd, %ld, %llx처럼 작성한다.
printf("%d", 0x10)은 16을, printf("%x", 125)는 7d를, %X는 7D를, %o는 175를 출력한다. 저장된 값을 어떤 진법의 문자열로 나타낼지를 변환기호가 결정한다.
문자와 문자열 출력
%c는 한 개의 문자를 출력하고, %s는 널 문자 '\0'로 끝나는 문자열을 출력한다. 따라서 printf("%s", "ab\0cd")는 널 문자 앞부분인 ab까지만 출력한다.
실수 출력
| 변환기호 | 출력 형식 |
|---|---|
%f | 일반적인 소수점 형식 |
%e, %E | 지수 형식, 지수 기호를 각각 소문자·대문자로 표시 |
%g, %G | 소수점 형식과 지수 형식 중 더 간결한 형식 |
예를 들어 12.34f를 %f로 출력하면 12.340000이 되고, 123.45678을 %e로 출력하면 1.234568e+02가 된다. %g는 값의 크기에 따라 123.457 또는 1.23457e-05처럼 간결한 표현을 선택한다.
4. printf 출력 양식의 편집
플래그, 최소 자릿수, 정밀도
변환기호에는 출력 모양을 수정하는 요소를 추가할 수 있다. - 플래그는 왼쪽 정렬, +는 부호 출력, 공백 플래그는 부호가 놓일 자리를 확보하고, 0은 앞의 빈자리를 0으로 채운다.
정수로 지정한 필드 폭은 출력을 위한 최소 자릿수를 뜻한다. 점(.) 뒤의 정수는 실수 출력에서 소수점 이하 자릿수 또는 최대 유효 자릿수를 지정한다.
| 출력양식 | 값 | 출력 결과의 의미 |
|---|---|---|
%5d | 123 | 폭 5에 오른쪽 정렬: 앞에 공백 2개 |
%-5d | 123 | 폭 5에 왼쪽 정렬: 뒤에 공백 2개 |
%+5d | 123 | + 부호를 표시하고 폭 5 확보 |
%+05d | 123 | +0123처럼 빈자리를 0으로 채움 |
%10.1f | 123.456 | 최소 폭 10, 소수점 이하 1자리로 반올림 |
%10.4g | 123.456 | 최소 폭 10, 최대 유효 숫자 4자리 |
필드 폭은 최소 폭이므로 실제 값이 더 길면 잘리지 않고 필요한 만큼 출력된다. 예를 들어 %+2d에 123을 출력해도 +123 전체가 나타난다.
5. scanf 함수의 구조
scanf의 용도와 주소 연산자
scanf() 함수는 지정된 양식으로 값을 입력받아 변수의 기억공간에 저장한다. 입력양식과 함께 값을 저장할 변수의 주소가 필요하므로 일반적인 변수 앞에 주소 연산자 &를 사용한다.
scanf("입력양식", &변수1, &변수2, ...);
입력양식에는 빈칸 또는 탭, %로 시작하는 변환기호, 그리고 %나 백색공백이 아닌 일반 문자를 넣을 수 있다. 일반 문자를 넣으면 실제 입력에도 그 문자가 같은 위치에 있어야 한다.
예를 들어 scanf("%f, %lf", &f, &d)는 1.23, 45.9e-4처럼 두 값 사이에 쉼표가 있는 입력을 기대한다. 양식의 쉼표와 사용자가 입력한 쉼표가 일치해야 한다.
printf는 값을 읽어 출력하므로 수식을 전달하지만, scanf는 입력값을 변수에 저장해야 하므로 변수의 주소를 전달한다.
6. scanf의 자료형별 변환기호
정수 입력
| 변환기호 | 입력 형식 |
|---|---|
%d | 부호 있는 10진 정수 |
%i | 표기에 따라 10진수, 0으로 시작하는 8진수, 0x로 시작하는 16진수 |
%u | 부호 없는 10진 정수 |
%o | 8진수 |
%x | 16진수 |
출력과 마찬가지로 h, l, ll을 붙여 short, long, long long을 구분한다. 예를 들어 %hi는 short형 정수를 진법 표기에 맞춰 입력하고, %llx는 long long형 16진수를 입력한다.
실수 입력
실수 입력에서 float형 변수에는 %f, double형 변수에는 %lf를 사용한다. scanf("%f %lf", &f, &d)에 1.23 45.9e-4를 입력하면 f에는 1.23, d에는 0.00459가 저장된다.
문자와 문자열 입력
%c는 한 문자를 입력하고 %s는 널 문자로 끝나는 문자열을 입력한다. 문자 배열의 이름은 배열의 시작 주소를 나타내므로 문자열 입력에서는 scanf("%s", str)처럼 배열 이름 앞에 &를 붙이지 않는다.
%s는 공백을 만나면 문자열 입력을 끝낸다. 따라서 문자 A를 입력한 뒤 Computer Science를 %s로 읽으면 str에는 Computer까지만 저장되고 출력도 A Computer가 된다.
출력의 %f는 float와 double 값을 모두 출력하는 데 사용하지만, scanf로 입력할 때는 float에 %f, double에 %lf를 사용한다는 차이를 기억해야 한다.
7. 문자 단위 입출력
getchar와 putchar
getchar()는 표준 입력 stdin의 현재 위치에서 문자 한 개를 입력한다. 입력한 문자는 ch = getchar();처럼 char형 변수에 저장할 수 있다.
putchar()는 표준 출력 stdout의 현재 위치에 문자 한 개를 출력한다. putchar(ch);처럼 출력할 문자를 인수로 전달한다.
char c;
printf("문자 하나를 입력하세요\n");
c = getchar();
printf("입력한 문자 = ");
putchar(c);
이 프로그램에 A를 입력하면 getchar가 A 한 문자를 읽고 putchar가 같은 문자를 출력한다. 형식 변환이 필요 없는 문자 하나의 입출력에 적합한 방식이다.
8. 문자열 단위 입출력
gets와 puts
gets()는 표준 입력 stdin의 현재 위치부터 행의 끝까지 문자열을 입력한다. 문자열 변수는 입력한 모든 문자를 충분히 저장할 수 있는 공간을 갖추어야 한다.
puts()는 표준 출력 stdout의 현재 위치부터 문자열을 출력하고, 출력이 끝나면 자동으로 줄을 바꾼다.
char str[100];
printf("문자열을 입력하세요\n");
gets(str);
printf("입력한 문자열 = ");
puts(str);
puts("KNOU");
Computer Science를 입력하면 gets는 공백을 포함하여 행 끝까지 읽으므로 전체 문자열이 저장된다. puts는 Computer Science를 출력한 뒤 자동으로 줄을 바꾸고 다음 KNOU를 새 행에 출력한다.
scanf("%s", str)는 공백에서 입력을 마치지만, 강의에서 다룬 gets(str)는 행의 끝까지 읽으므로 공백이 포함된 문자열을 입력할 수 있다.
핵심 개념 정리
- 함수는 특정 작업을 수행하도록 설계한 코드 블록이며 입력 데이터를 처리해 결과를 만들 수 있다.
- 표준 입력과 표준 출력은 프로그램이 사용자와 문자 시퀀스 형태의 데이터를 주고받는 기본 장치이다.
- printf는 출력양식 속 변환기호에 따라 정수, 문자, 문자열, 실수를 문자열로 변환해 출력한다.
- 정수 출력은 %d·%u·%o·%x, 문자와 문자열은 %c·%s, 실수는 %f·%e·%g 등을 사용한다.
- 출력 플래그와 필드 폭, 정밀도를 사용하여 정렬, 부호, 0 채움, 소수 자릿수를 조정할 수 있다.
- scanf는 입력양식에 따라 값을 변환하여 변수에 저장하므로 일반 변수의 주소를 전달한다.
- scanf의 실수 입력은 float에 %f, double에 %lf를 사용한다.
- getchar와 putchar는 문자 한 개, gets와 puts는 문자열 단위로 입출력한다.
- %s 입력은 공백에서 끝나지만 gets는 행 끝까지 읽고, puts는 출력 뒤 자동으로 줄을 바꾼다.
최종 정리: 입출력 함수의 핵심은 값의 자료형과 변환기호를 정확히 대응시키는 것이다. printf는 값을 원하는 문자 형식으로 출력하고, scanf는 사용자의 문자 입력을 자료형에 맞게 변환해 변수의 주소에 저장한다.
예상문제 20선
1. 함수의 의미로 가장 적절한 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
함수는 특정 작업이나 기능을 수행하도록 구성한 코드 블록이다.
2. 표준 출력 스트림을 나타내는 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
stdin은 표준 입력, stdout은 표준 출력을 나타낸다.
3. printf에서 부호 있는 10진 정수를 출력하는 변환기호는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③%d는 값을 부호 있는 10진 정수 문자열로 변환하여 출력한다.
4. printf("%X", 125)의 출력 결과는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④%X는 부호 없는 16진수를 영문 대문자로 출력하므로 125는 7D가 된다.
5. 문자열을 출력하는 printf 변환기호는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①%s는 널 문자로 끝나는 문자열을 출력한다.
6. printf("%s", "ab\0cd")의 출력 결과는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②%s는 널 문자를 문자열의 끝으로 인식하므로 그 앞의 ab까지만 출력한다.
7. 소수점 형식과 지수 형식 중 간결한 형식을 선택하는 변환기호는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③%g는 값에 따라 소수점 또는 지수 표현 중 더 간결한 방식을 사용한다.
8. printf 출력 플래그와 기능의 연결로 옳지 않은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
마이너스 플래그는 지정한 필드 안에서 값을 왼쪽으로 정렬한다.
9. printf("%+05d", 123)의 출력 결과는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
+는 부호를 표시하고 0은 폭 5의 앞 빈자리를 0으로 채우므로 +0123이 된다.
10. scanf에서 일반 변수 앞에 &를 사용하는 이유는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
scanf는 입력한 값을 변수의 기억공간에 기록해야 하므로 그 주소가 필요하다.
11. scanf에서 표기에 따라 10진·8진·16진 정수를 구별해 입력하는 기호는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③%i는 입력의 앞부분을 보고 10진수, 0으로 시작하는 8진수, 0x로 시작하는 16진수를 구별한다.
12. scanf로 double형 변수에 실수를 입력할 때 사용할 변환기호는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
scanf 실수 입력에서 float에는 %f, double에는 %lf를 사용한다.
13. scanf("%f, %lf", &f, &d)에 맞는 입력은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
입력양식에 일반 문자 쉼표가 있으므로 실제 입력에도 같은 위치에 쉼표가 있어야 한다.
14. scanf("%s", str)가 문자열 입력을 끝내는 지점은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②%s 입력은 공백으로 구분되므로 Computer Science를 입력하면 Computer까지만 읽는다.
15. 문자 배열 str에 문자열을 입력하는 올바른 문장은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
문자열 입력에는 %s를 사용하며 배열 이름 자체가 시작 주소를 나타내므로 앞에 &를 붙이지 않는다.
16. 표준 입력에서 문자 한 개를 읽는 함수는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④
getchar는 stdin의 현재 위치에서 한 문자를 입력한다.
17. 표준 출력에 문자 한 개를 출력하는 함수는?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ①
putchar는 전달받은 한 문자를 stdout의 현재 위치에 출력한다.
18. 강의에서 다룬 gets 함수의 동작은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ②
gets는 stdin의 현재 위치에서 행 끝까지 읽으므로 공백이 포함된 문자열도 입력한다.
19. puts 함수의 특징으로 옳은 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ③
puts는 stdout에 문자열을 출력하고 마지막에 자동으로 행을 바꾼다.
20. 공백이 포함된 Computer Science 전체를 강의의 함수로 입력하기에 적절한 것은?
정답입니다.
오답입니다. 답안을 다시 선택해 보세요.
정답 및 해설 보기
정답: ④%s는 공백에서 끝나지만 gets는 행 끝까지 읽으므로 공백을 포함한 전체 문자열을 입력한다.
댓글
댓글 쓰기