이때까지 썼던 printf함수, scanf함수 모두 표준 입출력 함수입니다.
버퍼
이런 표준 입출력 함수를 통해 데이터를 입출력 하는경우 해당 데이터들은 운영체제가 제공하는 '메모리 버퍼'를 중간에 통과하게 됩니다.
메모리 버퍼는 데이터를 임시로 모아두는(저장하는) 메모리 공간입니다.
키보드로 입력된 데이터가 입력스트림을 거쳐서 입력 버퍼로 들어가는 시점은 엔터 키가 눌리는 시점입니다.
엔터키를 누르기 전에는 fgets 함수가 문자열을 읽어 들이지 못하는 것입니다.
엔터키를 누르기 전까지는 입력버퍼가 비워져 있습니다.
스트림
먼저 입력이란 프로그램 안으로 데이터가 흘려 들어오는 것을 말합니다. 대표적인 입력 장치로 키보드, 파일이 있습니다.
출력이란 프로그램 밖으로 데이터가 흘러 나가는 것을 말합니다. 대표적인 입력 장치로 모니터, 파일이 있습니다.
프로그램과 키보드는 기본적으로 연결되어 있는 개체가 아닌, 서로 떨어져 있는 개체입니다. 따라서 프로그램 상에서 입출력하려면 이 개체를 연결시켜주는 다리가 필요합니다.
이 다리의 역할을 하는 매개체를 가리켜 '스트림(stream)'이라고 합니다.
스트림은 운영체제에서 제공하는 소프트웨어적인 데이터 송수신의 도구가 되는 스트림을 제공합니다.
콘솔과의 연결을 위한 스트림은 필요 없고, 파일과의 연결은 스트림의 생성은 우리가 직접 요구해야 합니다.
그래서 콘솔 입출력을 위한 스트림을 자동으로 생성이 됩니다.
정리를 해보면
콘솔 입출력을 위한 '입력 스트림'과 '출력 스트림'은 프로그램이 실행되면 자동으로 생성되고 프로그램이 종료되면 자동으로 소멸된다.
이 둘(입력 스트림, 출력 스트림)은 기본적으로 제공되는 표준 스트림(standard stream)입니다.
아래는 스트림 종류입니다.
- stdin - 표준 입력 스트림 (키보드 대상으로 입력)
- stdout - 표준 출력 스트림 (모니터 대상으로 출력)
- stderr - 표준 에러 스트림 (모니터 대상으로 출력)
스트림의 의미: 스트림은 한 방향으로 흐르는 데이터의 흐름을 뜻합니다. (단 방향으로만 데이터의 전송이 이뤄짐)
버퍼링(buffering)을 하는 이유는?
버퍼링이란 버퍼를 활용하는 방식 또는 버퍼에 저장하는 것을 말합니다.
가장 큰 이유는 '데이터 전송의 효율성'과 관련이 있습니다.
키보드나 모니터와 같은 외부 장치와의 데이터 입출력은 생각보다 시간이 걸리는 작업입니다.
따라서 버퍼링 없이 키보드가 눌릴 때마다 눌린 문자의 정보를 목적지로 바로 이동시키는 것보다 중간에 메모리 버퍼를 둬서 데이터를 한데 묶어서 이동시키는 것이 보다 효율적이고 빠릅니다.
모니터에 입출력 말고도 파일을 대상으로도 호출이 가능합니다. 인자로 파일의 스트림 정보가 전달되면 해당 버퍼에 저장되어 있던 데이터들이 버퍼를 떠나서 파일에 기록됩니다.
스트림을 통한 입출력
#include <stdio.h>
int main(void) {
char perID[7];
char name[10];
fputs("주민번호 앞 6자리 입력:", stdout);
fgets(perID, sizeof(perID), stdin);
getchar(); //입력 버퍼 비움
fputs("이름 입력:", stdout);
fgets(name, sizeof(name), stdin);
printf("주민번호 %s \n", perID);
printf("이름 %s \n", name);
return 0;
}
결과
주민번호 앞 6자리 입력:000101
이름 입력:Plorence
주민번호 000101
이름 Plorence
댓글