본문 바로가기

C 언어

C 언어: scanf 사용 시 입력 버퍼 비우는 방법

 

프로그래밍에서 버퍼는 상대적으로 느린 입출력 장치의 속도를 보완하고자 임시기억공간인 버퍼를 만들어서 데이터를 저장하고 한번에 전달하는 역할을 한다. 비유하자면 마치 마트에서 물건을 하나씩 가져가서 계산하는 것보다 버퍼라는 카트에 필요한 물건들을 한번에 담고 계산대로 이동하는 것과 같다. 

 

여기서 scanf 함수는 버퍼를 이용해서 사용자에게 데이터를 입력 받는 함수이다. 

이 함수를 사용해서 데이터를 입력하면 데이터는 입력 버퍼에 임시저장되었다가, 그 데이터를 scanf가 즉시 처리하여 변수에 할당한다. 

 

해당 원리를 염두하고, scanf 함수로 세 개의 문자를 입력받고 출력하는 예제 코드문을 읽어보자.  

c1 = 'a'

c2 = 'b'

c3 = 'c' 를 입력하는 것이 목표이다. 

#include <stdio.h>
#pragma warning (disable: 4996)

int main(void) {
	char c1;
	char c2;
	char c3;

	printf("1번째 문자를 입력하시오:");
	scanf("%c", &c1); //a입력하고 enter  
	printf("2번째 문자를 입력하시오:");
	scanf("%c", &c2); //b입력하고 enter 
	printf("3번째 문자를 입력하시오:");
	scanf("%c", &c3); //c입력하고 enter 

	printf("%c", c1);
	printf("%c", c2);
	printf("%c", c3);

	return 0;
}
1번째 문자를 입력하시오:a
2번째 문자를 입력하시오:
3번째 문자를 입력하시오:b

//출력결과
a

b

 

출력 결과를 보면,  c2에 문자 입력을 할 수 없게 건너뛰어지고, c3 문자 입력으로 넘어가게 된다.

출력을 하면, c2는 공백이 출력된다.
왜 이런 현상이 발생할까? 

 

왜냐하면 scanf로 문자를 입력할 때,  우리가 c1에서 'a'를 입력하고 엔터를 치면 입력버퍼에 enter를 의미하는 "\n"도 같이 버퍼에 들어가버리기 때문이다. 

 

 

그래서, c1 = a 가 할당 된 후 버퍼에 남아있는 엔터 키가 그 다음 변수의 문자 입력을 방해하게 되는 것이다.

 

이 문제를 해결하려면 getchar 함수가 필요하다. 

getchar 함수는 문자를 한 글자씩 읽어들인다는 특징이 있는데, 이 특징을 이용하면 버퍼에서 엔터 키까지 깔끔하게 비워줄 수 있다.  

while (getchar() != '\n');

 

해당 구문은 엔터 키('\n')를 만날 때까지 문자를 읽어들여서 입력버퍼를 비우고, 엔터 키를 만나면 읽기를 종료하는 구문이다. 엔터 키를 만나면서 루프가 종료 되니까 엔터 키까지 버퍼에서 완전히 비워지게 된다. 

 

이제 getchar를 적용한 코드문을 사용하면 c2에 문자를 정상적으로 입력할 수 있다. 

#include <stdio.h>
#include <string.h>
#pragma warning (disable: 4996)

int main(void) {
    char c1;
    char c2;
    char c3;

    printf("1번째 문자를 입력하시오:");
    scanf("%c", &c1); 
    while (getchar() != '\n');
    printf("2번째 문자를 입력하시오:");
    scanf("%c", &c2); 
    while (getchar() != '\n');
    printf("3번째 문자를 입력하시오:");
    scanf("%c", &c3); 
    while (getchar() != '\n');

    printf("%c\n", c1);
    printf("%c\n", c2);
    printf("%c\n", c3);

    return 0;
}
1번째 문자를 입력하시오:a
2번째 문자를 입력하시오:b
3번째 문자를 입력하시오:c
a
b
c