스트림 및 버퍼
스트림은 입출력 및 에러 전달 과정 등 데이터의 흐름을 추상화한 개념이다. 구체적으로는 이 흐름을 구성하는 일련의 데이터 요소를 말한다. C++에서는 특히 표준 입력, 표준 출력, 표준 에러 스트림이 존재하고, 입력은 키보드와 같은 입력 장치에서 데이터를 받아 프로그램으로 전달하며, 출력과 에러는 프로그램에서 생성된 데이터를 출력 장치, 예를 들어 디스플레이로 전달한다.
입출력 스트림에는 버퍼가 사용되는 경우가 많은데, 일시적으로 데이터들을 저장하는 곳이라 보면 된다. 데이터를 입력받은 그 즉시 전달하는 것이 아니라 일정 수준, 혹은 전달하는 특정한 입력이 있을 때까지 버퍼에 저장해두었다가 전달하는 것이다. 예를 들어서 std::cin
은 사용자가 공백문자나 개행문자를 입력하기 전까지 버퍼에 저장해두었다가 공백문자나 개행문자가 입력되면 이를 전달한다. 덕분에 입력시에 수정이 가능하고, 여러 데이터를 한번에 처리하여 성능을 최적화할 수 있다. 단 버퍼가 꽉 차거나 필요없는 문자가 버퍼에 들어가는 경우 버퍼를 비워줘야 할 수 있다.
단 버퍼를 사용하지 않을 수도 있다. 예를 들어 키가 입력되는 즉시 프로그램에 전달이 필요하다면, 버퍼를 사용하지 않아야 한다. 이를 저수준 입출력 방식(raw level console I/O)라 하는데 C++ 표준으로 지원되지 않는다. 기본적으로 C++은 스트림 입출력을 지원한다.
표준 입출력 스트림 객체
표준 입출력 스트림을 사용하기 위해서는 아래와 같이 iostream
을 추가해주어야 한다.
#include <iostream>
using namespace std;
cin
istream
타입의 스트림 객체로 키보드 장치와 연결되며 버퍼를 사용한다.
cout
ostream
타입의 스트림 객체로 스크린 장치와 연결되며 버퍼를 사용한다.
cerr
ostream
타입의 스트림 객체로 스크린 장치와 연결되며,기본적으로 오류 메시지를 출력하는 것이 목적인데, 스트림 내부 버퍼를 거치지 않고 출력된다.
clog
ostream
타입의 스트림 객체로 스크린 장치와 연결되며, 기본적으로 오류 메시지를 출력하는 것이 목적인데 , 스트림 내부 버퍼를 거쳐 출력된다.
표준 입출력 스트림 멤버 함수
ostream
타입의 스트림 객체는 대표적으로 아래 멤버 함수를 사용할 수 있다.
// ch를 스트림에 출력
ostream& put(char ch)
// str 배열에 있는 n개의 문자를 스트림에 출력
ostream& write(char* str, int n)
// 현재 스트림 버퍼를 강제 출력
ostream& flush()
istream
타입의 스트림 객체는 대표적으로 아래 멤버 함수를 사용할 수 있다.
// 입력 스트림에서 문자를 읽어 리턴하는데 오류나 EOF를 만나면 -1 반환
int get();
// 입력 스트림에서 문자를 읽어 ch에 저장 후 현재 입력 스트림 객체 참조 반환
istream& get(char& ch);
// 입력 스트림에서 최대 n-1개의 문자를 읽어 str에 저장하며, 개행문자를 만나면 종료 후 개행문자는 버퍼에 남김
istream& get(char* str, int n);
// 입력 버퍼에서 최대 n개의 문자를 무시하거나 특정 종료 조건 문자 delim을 만날 때까지 무시
istream& ignore(int n = 1, char delim = EOF);
// 입력 스트림에서 최대 n-1개의 문자를 읽어 str에 저장하며, 개행 문자를 버퍼에서 제거
istream& getline(char* str, int n);
단 istream& get(char* str, int n)
은 문자를 읽는 도중에 개행문자를 만나면 지금까지의 버퍼를 전달하는데, 이때 개행문자를 처리하지 않고 입력 버퍼에 남겨둔다. 그런데 입력 버퍼에 개행문자가 남아있는 것이 문제될 가능성이 높기 때문에 이 경우에는 버퍼를 강제적으로 비워줘야 한다.
istream& get(char* str, int n)
외에도 std::cin >>
연산자, std::scanf()
를 이용할 때는 버퍼에 개행문자가 남기 때문에 비워주어야 한다.
버퍼를 비울 때는 istream& get(char& ch)
, istream& ignore(int n = 1, char delim = EOF)
을 사용하면 된다.
'Language > C & C++' 카테고리의 다른 글
[C++] 파일 입출력 스트림(file I/O stream) 및 파일 포인터(file pointer) (0) | 2024.12.06 |
---|---|
[C++] 포맷 플래그(format flag) 및 조작자(manipulator) (0) | 2024.12.04 |
[C++] 람다(lambda) 표현식 (0) | 2024.11.15 |
[C++] auto 키워드 (0) | 2024.11.14 |
[C++] 표준 템플릿 라이브러리(STL) (0) | 2024.11.14 |