C 언어에서 버퍼(Buffer)란 무엇인가?
버퍼(buffer)란 데이터를 일시적으로 보관하는 임시 저장 공간을 의미합니다. 키보드, 모니터 등 모든 입출력(I/O) 장치에는 자체적인 I/O 버퍼가 존재하며, 이 버퍼는 프로그램과 입출력 장치 사이에서 데이터의 흐름을 원활하게 해주는 중간 창구 역할을 합니다.
입력 버퍼에 데이터가 남는 이유
프로그램이 요청한 개수보다 더 많은 값을 입력으로 전달하면, 초과된 값들은 자동으로 입력 버퍼(input buffer)에 남게 됩니다. 문제는 이렇게 남아 있는 데이터가 다음 입력 함수가 호출될 때 자동으로 전달될 수 있다는 점입니다.
따라서 새로운 입력을 받기 전에는 반드시 버퍼를 비워 주는 것이 올바른 프로그래밍 습관입니다.
예제 코드
다음은 버퍼의 동작을 확인할 수 있는 C 프로그램 예제입니다.
#include<stdio.h>
void main(){
int a,b;
printf("\n Enter a value: ");
scanf("%d",&a);
printf("\n Enter b value: ");
scanf("%d",&b);
printf("\n a+b=%d ",a+b);
getch();
}
정상적인 실행 결과
위 프로그램을 실행하고 각각 값을 하나씩 입력하면 다음과 같은 결과가 출력됩니다.
Enter a value: 1 Enter b value: 2 a+b=3
버퍼에 값이 남아 있을 때의 실행 결과
이번에는 프로그램을 다시 실행하고, a 값만 입력하는 것이 아니라 한 줄에 여러 값을 함께 입력해 보겠습니다.
Enter a value: 1 2 3 Enter b value: a+b=3
흥미롭게도 b 값을 입력하지 않았는데도 프로그램은 정상적으로 덧셈 결과를 출력했습니다. 그 이유는 첫 번째 입력 시 함께 입력했던 "2"가 입력 버퍼에 그대로 남아 있었고, 두 번째 scanf()가 별도의 키보드 입력 없이 버퍼에 저장된 값을 그대로 가져다 사용했기 때문입니다.
버퍼를 비우는 함수 정리
실제 구현에서 표준 입력 버퍼의 데이터를 제거해야 할 때는 flushall() 또는 fflush() 함수를 사용합니다.
flushall() − stdio.h 헤더 파일에 미리 정의되어 있는 함수로, I/O 버퍼에 남아 있는 데이터를 모두 제거할 수 있습니다.
fflush() − stdio.h 헤더 파일에 정의된 함수로, 입력 버퍼 또는 출력 버퍼의 메모리를 비우는 데 사용됩니다.
fflush(stdin) − 입력 버퍼 메모리를 비우는 용도로 사용되며,
scanf()문장을 작성하기 전에 호출하는 것이 권장됩니다.fflush(stdout) − 출력 버퍼 메모리를 비우는 용도로 사용되며,
printf()문장을 작성하기 전에 호출하는 것이 권장됩니다.
참고: fflush(stdin) 사용 시 주의점
C 표준에서 fflush()의 동작은 출력 스트림에 대해서만 정의되어 있습니다. 따라서 fflush(stdin)처럼 입력 스트림에 사용하는 것은 컴파일러나 플랫폼에 따라 동작이 달라질 수 있는 정의되지 않은 동작(undefined behavior)입니다. Visual Studio 같은 일부 환경에서는 지원하지만, 이식성이 중요한 코드라면 getchar()를 반복 호출해 버퍼에 남은 문자를 소진하는 방식 등을 사용하는 것이 더 안전합니다.