C

입출력 함수와 버퍼

1space 2025. 6. 12. 20:01

프로그램과 입출력 장치 사이의 연결 – 스트림(stream)

프로그래밍에서 입력은 키보드로부터, 출력은 모니터로 나가는 것이 일반적입니다.
하지만 키보드와 모니터는 물리적으로 프로그램과 직접 연결되어 있지 않기 때문에,
운영체제는 프로그램과 입출력 장치 사이를 연결해주는 논리적인 통로를 만들어 놓습니다.

이 통로를 스트림(Stream) 이라고 합니다.
스트림은 데이터를 보내고 받는 길이며, 프로그램은 이 경로를 통해 입력과 출력을 처리합니다.

  • 입력 스트림: 키보드 → 프로그램
  • 출력 스트림: 프로그램 → 모니터

 

버퍼(buffer)의 필요성

CPU는 매우 빠르지만, 키보드나 모니터 같은 입출력 장치는 상대적으로 느립니다.
예를 들어, 사용자가 apple을 입력한다고 가정하면,
각 문자를 하나씩 바로바로 프로그램으로 전송하는 방식은 매우 비효율적입니다.

이러한 속도 차이를 해결하기 위해 버퍼(buffer) 라는 임시 저장 공간을 사용합니다.
버퍼는 데이터를 일단 모아두었다가, 한 번에 처리하는 역할을 합니다.

입력의 경우에도 apple이라는 문자열을 입력하면,
해당 문자열은 프로그램으로 바로 전달되지 않고, 먼저 입력 버퍼에 저장됩니다.
사용자가 Enter 키를 누르는 순간, 버퍼에 저장된 내용이 한 번에 프로그램으로 전달됩니다.

 

scanf 함수의 실제 동작

scanf 함수는 일반적으로 키보드로부터 데이터를 입력받는 함수로 알려져 있습니다.
하지만 엄밀히 말하면, scanf는 키보드가 아닌 버퍼에서 데이터를 읽어오는 함수입니다.

예시:

char c;
scanf("%c", &c);

위 코드를 기준으로 사용자가 happy라고 입력하고 Enter를 누르면,
버퍼에는 "h", "a", "p", "p", "y", "\n" 이 순서대로 저장됩니다.
scanf("%c", &c);는 이 중에서 맨 앞의 문자 'h'만 읽어서 변수 c에 저장합니다.
버퍼에는 나머지 "a", "p", "p", "y", "\n"이 여전히 남아 있는 상태입니다.

따라서 scanf는 키보드로부터 직접 입력받는 함수가 아니라,
버퍼에 있는 내용을 형식에 맞추어 꺼내오는 함수
입니다.

 

버퍼로 인한 문제 – 줄바꿈 문자(\n) 문제

버퍼는 매우 유용한 구조이지만,
때때로 프로그램이 예상하지 못한 입력 오류를 일으키기도 합니다.

예시:

char c1, c2;
scanf("%c", &c1);
scanf("%c", &c2);

사용자가 a를 입력하고 Enter를 누르면,
버퍼에는 "a", "\n"이 저장됩니다.

첫 번째 scanf("%c", &c1);는 "a"를 꺼내어 c1에 저장합니다.
하지만 두 번째 scanf("%c", &c2);는 남아 있던 "\n"을 꺼내게 되어,
사용자는 아무것도 입력하지 않았지만 c2에 줄바꿈 문자가 저장되는 결과가 발생합니다.

 

 

getchar 함수의 특징

getchar() 함수는 문자 하나를 버퍼에서 꺼내오는 함수입니다.
이 함수는 scanf("%c", &c);와 유사하게 동작하지만, 오직 문자 하나만 입력받는 데 특화되어 있습니다.

예시:

char c1, c2;
c1 = getchar();
c2 = getchar();

사용자가 a를 입력하고 Enter를 누르면,

  • c1 = 'a'
  • c2 = '\n' 이 저장되어, 두 번째 입력이 씹히는 현상이 발생합니다.

따라서 getchar()를 사용할 때도, 필요에 따라 버퍼 비우기 코드를 함께 작성해야 합니다.

 

 

버퍼 비우기 – 해결 방법

이 문제를 해결하려면 버퍼에 남아 있는 데이터를 비워주는 작업이 필요합니다.
가장 일반적인 방법은 다음과 같습니다.

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

위 코드는 버퍼에서 줄바꿈 문자가 나올 때까지 문자를 하나씩 꺼내 버립니다.
이렇게 하면 버퍼가 초기 상태로 비워지기 때문에, 다음 입력 시 문제가 발생하지 않습니다.

개선된 예시:

char c;
scanf("%c", &c);
while(getchar() != '\n'); // 버퍼 비우기

 

요약

스트림 프로그램과 입출력 장치를 연결하는 논리적인 통로
버퍼 느린 입출력 장치를 보완하기 위한 임시 저장소
scanf 키보드에서 직접 입력받는 것이 아니라 버퍼에서 데이터를 꺼냄
getchar 문자 하나를 버퍼에서 꺼내오는 함수
\n 문제 엔터키로 인해 남은 줄바꿈 문자가 다음 입력에 영향을 줌
해결 방법 while(getchar() != '\n');를 통해 버퍼를 비워줌

'C' 카테고리의 다른 글

배열  (0) 2025.06.12
난수 생성  (0) 2025.06.12
제어문 - while / do while문  (0) 2025.06.12
제어문 - for / 이중for문  (0) 2025.06.12
제어문 - if / switch문  (0) 2025.06.11