[C언어] : scanf()함수 입력 무시 문제, 버퍼링

728x90

 

scanf("%d\n", &a);

가끔 이걸 쓸 때 빌드하고 터미널에서 값을 입력하면 이상하게도 그냥 무시되는 경우가 있었다. 그리고는 다시 문자나 문자열 입력을 요구하기도 한다.특히 연속으로 scanf 사용하는 경우에 문제가 발생하는 경우가 많다.

 

scanf() 함수는 데이터를 입력 받을 때 버퍼를 이용하는데, 버퍼에 가져올 값이 없으면 사용자에게 데이터를 입력 받게 하기 위해 모니터 화면에 커서를 깜빡거리게 한다.그리고 사용자가 키보드로 데이터를 입력한 후 Enter를 치면, 그 때 입력한 데이터와 Enter값이 한꺼번에 키보드 버퍼에 들어가게 된다.

 

* 버퍼 참고

이러한 방식을 버퍼링(buffering)이라고 한다.

 

예시 코드)

#include <stdio.h>

int main(void)
{
	int a;
    char b;
    
    scanf("%d", &a);
    scanf("%c", &b);
    
    printf("a값 : %d \nb값 : %c", a, b);
    printf("b값에 저장된 값 : %d", b);
    return 0;
}

a에서 정수를 입력받게 되지만, b에 값을 입력받지도 않았는데도 두번째 scanf 함수가 개같이 무시되었다.출력 결과 값은 다음과 같다.

 

입력 -> 111
출력 ->
a값 : 111
b값 : 
b값에 저장된 값 : 10

b값은 입력하지도 않았는데 정수로 출력해보니 10이 들어가 있었음을 알게 되었다. 아스키코드값으로 LF(new line)의 값을 정수로 바꾸면 10이 되므로 b값은 공백이 아니라 enter값이 저장되어 있는 셈이다.

 

1 : 키보드로 123을 입력
2 : 버퍼에 123을 저장
3 : 변수 a에 123을 저장
4 : 키보드로 엔터를 입력
5 : 버퍼에 엔터값을 저장
6 : 변수 b에 엔터값을 저장

 

따라서 우리는 버퍼 내에서 찌꺼기 값으로 존재하는 Enter의 데이터를 없애야만 한다. 이것을 입력 버퍼를 지우는 방법이라고도 한다.

 

해결법 1)
일단 scanf안에 \n이 있다면 지워서 빌드 해본다.
해결법 2)
fflush(stdin);
키보드 버퍼를 지우는 기능이다. 하지만 gcc에서는 안된다고 한다. 최신 버전의 vsc에서는 아마 지원되지 않는 방법인  것 같다.
해결법 3)
scanf안에 공백을 넣는다. 
scanf(" %c", &b); 이런 식으로 사용.
문자 입력 중에 공백을 무시하고 그 외의 문자를 입력 받도록 한다.
해결법 4)
%*c를 추가한다.
enter값 입력은 받지만 저장은 하지 않는 방법으로 버퍼를 비워버리는 방법이다.
scanf("%*c %c", &b);

1 : 키보드로 123을 입력
2 : 버퍼에 123을 저장
3 : 변수 a에 123을 저장
4 : 버퍼에 enter값을 저장
5 : scanf("%*c")가 enter값을 무시
6 : 버퍼에 아무 것도 남지 않음
해결법 5)
scanf() 함수들 사이에 getchar() 함수를 사용한다.
앞에서 입력한 Enter값이 버퍼에 남아있더라도 이를 입력버퍼에서 비워 버린다.
scanf("%d", &a);
getchar();
scanf("%c", &b);

https://afterdawncoding.tistory.com/42

 

[C언어] 문자 입출력 함수 getchar(), putchar()

stdio.h 헤더를 사용하는 입출력 함수들이다. getchar()는 입력을 받고, putchar()는 문자를 출력한다. #include int main() { char text=0; while(text != EOF) { text=getchar(); putchar(text); } return 0; }..

afterdawncoding.tistory.com

 

728x90