scanf 함수의 개념은 "입력 버퍼(stdin)에서 format에서 지정한 대로 읽어들
인다" 입니다. 위의 두개의 차이는 다음과 같습니다.
"%d %d" - stdin에서 숫자, 1자 이상의 공백문자(white-space character), 숫
자를 읽어들인다.
"%d %d\n" - stdin에서 숫자, 1자 이상의 공백문자, 숫자, 1자 이상의 공백문
자를 읽어들인다.
C99의 FCD인 N869 문서의 7.19.6.2.5절을 인용하겠습니다.
A directive composed of white-space character(s) is executed by reading
input up to the first non-white-space character (which remains unread),
or until no more characters can be read.
형식(format) 문자열에 있는 공백문자(white-space)는 그 다음에 공백 문자가
아닌 문자(non-white-space)가 올때까지 입력버퍼(stdin)에서 읽어들이라는
뜻입니다. 즉, "%d %d\n"는 숫자 2개, 1자 이상의 공백문자, 공백문자가 아닌
문자를 받아야만 입력이 완전하게 끝나는 것입니다. 참고로 "%d %d\n"과 "%d
%d ", "%d %d\t"는 같은 뜻을 가집니다.
말이 어렵게 되어버렸는데, 예제로 설명하겠습니다.
scanf("%d %d", &a, &b);
숫자값, 1자 이상의 공백문자, 숫자값이 입력버퍼에 있기를 기대한다.
숫자값, 1자 이상의 공백문자, 숫자값까지 읽어들인다. 그 나머지는 입력 버
퍼(stdin)에 그대로 놔둔다.
실행 결과 - 1 2를 입력했을 경우 형식(format) 문자열과 완벽히 일치한다.
그러므로 a와 b에 읽어들인 값을 저장하고 함수(scanf)를 종료한다.
scanf(%d %d\n", &a, &b);
숫자값, 1자 이상의 공백문자, 숫자값, 1자 이상의 공백문자, 공백문자가 아
닌 문자가 입력버퍼에 있기를 기대한다.
숫자값, 1자 이상의 공백문자, 숫자값, 1자 이상의 공백문자까지 읽어들인다.
그 나머지는 입력 버퍼(stdin)에 그대로 놔둔다.
실행 결과 - 1 2를 입력했을 경우 "%d %d"까지 일치가 되지만 \n 문자 때문에
1자 이상의 공백문자와 그 뒤에 공백문자가 아닌 문자를 기다리게 됩니다. 여
기에 3을 또 입력하게 되면 공백문자까지 읽어들이게 되고 나머지(3)는 그대
로 입력버퍼에 남게 됩니다. 이 남아있는 3은 다음 scanf문이 실행될 때 영향
을 주게 됩니다.
그리고 한가지 더. 다음의 예제 코드를 봐 주십시오.
#include <stdio.h>
int main(void)
{
int a, b;
printf("\n>>");
scanf("%d %d\n", &a, &b);
scanf("%d %d\n", &a, &b);
return 0;
}
이 프로그램의 실행 결과는 다음과 같습니다.
$ gcc 3.c -o 3
plsj@localhost: ~
$ ./3
>>1 2 <- 1과 2를 입력한다.
3 <- 숫자 2개가 입력되었는데도 입력을 기다린다. 3을 입력한다.
[1,2] <- 입력된 숫자 출력
>>4 5 <- 숫자 2개를 또 입력
[3,4] <- 4 5를 출력하는게 아니라 3과 4를 출력한다.
>>plsj@localhost: ~
$ ./3
>>1 2 <- 1과 2를 입력한다.
a <- 숫자 2개가 입력되었는데도 입력을 기다린다. 3을 입력한다.
[1,2] <- 입력받은 값을 출력한다.
>>[1,2] <- 여기에서 입력을 한번 받아야되는데 받지 않고 입력받은 값을
또한번 출력한다.
>>plsj@localhost: ~
$
첫번째 실행에서 1 2가 입력되면, "%d %d\n" 중에서 "%d %d"까지 일치가 됩니
다. 그러나 \n이 남아있기 때문에 1자 이상의 공백문자와 공백문자가 아닌 문
자의 입력을 기다리게 됩니다. 여기에 3을 입력하면 3 이전의 공백문자까지
읽어들이게 되어 첫번째 scanf 함수가 끝나게 되고 3은 입력버퍼에 그대로 남
습니다. 그다음의 scanf 함수가 실행되면 입력버퍼에 있는 3을 읽어들이게 되
고 " %d\n"이 남게 됩니다. 여기에 4 5를 입력하게되면 "4 "까지 읽어들이게
되고 5는 그대로 입력버퍼에 남게 됩니다. 즉 a에는 3이, b에는 4가 입력되는
것이죠.
두번째 실행에서도 마찬가지 입니다. 다만 첫번째 scanf 함수가 끝난 후에 3
대신 a가 입력버퍼에 남게 되고, 두번째 scanf 함수가 실행되면 형식(format)
문자열의 %d가 a와 일치가 안되기 때문에 두번째 scanf 함수는 하는일 없이
그대로 끝나게 됩니다. 따라서 1 2가 두번 출력되게 됩니다.
'프로그래밍 > C' 카테고리의 다른 글
Makefile 만들기 (0) | 2013.06.04 |
---|---|
TCP/IP소켓 프로그래밍 개요 및 기초소스. (0) | 2013.05.22 |
Stack 과 heap (메모리구조) (0) | 2013.04.19 |
kernel 에서 쓰이는 자료구조 red black tree (3) | 2013.04.19 |
Visual studio가 잊어버리게 하는 개념(compile with gcc) (0) | 2013.04.19 |