C++에서는 흔히 스트림의 출발지와 목적지로 콘솔, 파일, 스트링을 사용합니다.
※ 파일 끝을 나타내는 EOF(end of file)은 유닉스와 리눅스에서는 Ctrl+D를 사용하고 윈도우에서는 Ctrl+Z를 사용합니다.
1. 출력 스트림에서 제공하는 메서드
대표적인 cout은 빼고 정리했습니다.
cin | 입력 스트림. '입력 콘솔'에 들어온 데이터를 읽는다. |
cout | 버퍼를 사용하는 출력 스트림. 데이터를 '출력 콘솔'에 쓴다. |
cerr | 버퍼를 사용하지 않는 출력 스트림. 데이트를 '에러 콘솔'에 슨다. |
clog | 버퍼를 사용하는 cerr |
※ 버퍼를 사용하는 것과 사용하지 않는 것의 차이와 장점은?
버퍼를 사용하는 스트림은 받은 데이터를 버퍼에 저장했다가 블록 단위로 목적지로 보내고, 버퍼를 사용하지 않는 스트림은 데이터가 들어오자마자 목적지로 보내는데, 버퍼링(buffering)하는 이유는 파일과 같은 대상에 입출력을 수행할 때는 블록 단위로 묶어서 보내는 것이 효율적이기 때문입니다.
write | 출력 동작을 갖춘 객체나 변수가 아닌 문자 배열 하나 인수로 받는다. |
put | 출력 동작을 갖춘 객체나 변수가 아닌 문자 하나를 인수로 받는다. |
flush | 스트림의 버퍼를 명시적으로 비운다. |
good | 스트림을 정상적으로 사용할 수 있는 상태인지 확인한다. 사용할 수 없는 상태일 때 원인은 알려주지 않는다. |
fail | 최근 수행한 연산에 오류가 발생했는지 확인할 수 있다. ※ cout.fail() == !cout |
clear | 스트림 에러 상태를 초기화 한다. |
bad | 사용할 수 없는 상태일때 원인을 알려주는 함수이다. |
2. 입력 스트림 메서드
입력 스트림을 이용하면 일반 데이터 뿐 만 아니라 구조화된 데이터도 쉽게 읽을 수 있습니다.
<< | >> 연산자의 기본 설정에 따르면 공백을 기준으로 입력된 값을 토큰 단위로 나눕니다. 따라서 공백을 담을 수 없다. |
get | 입력값에 공백을 담을 수 있습니다. 스트림의 끝에 도달할 때까지 이름을 계속 읽는다. |
unget | 데이터를 다시 입력 소스 방량으로 보낼 수 있다. 그래서 이전에 읽은 문자를 스트림으로 되돌린다. |
putback | unget과 마찬가지로 입력 스트림을 한 문자만큼 되돌린다. |
peek | get을 호출할 때 리턴될 값을 미리 보여준다. |
getline | 미리 설정한 버퍼가 가득 채워질 때 까지 문자 한 줄을 읽는다. 이 때 문자 한 줄의 끝을 나타내는 \0(EOF end-of-line)문자도 버퍼의 크기에 포함된다. |
3. 입출력 매니퓰레이터
C++의 스트림은 단순히 데이터만 전달하는데 그치지 않고, 매니퓰레이터mamipulator(조종자)라는 객체를 받아서 스트림의 동작을 변경할 수 있다. 이때 스트림의 동작을 변경하는 작업만 할수도 있고, 스트림에 데이터를 전달하면서 동작도 변경할 수 있다.
boolalpha, noboolalpha | (boolalpha)스트림 bool 값을 true나 false로 출력하거나, (noboolalpha)1이나 0으로 출력하도록 설정한다. |
hex, oct, dec | 16진수(hexadecimal), 8진수(octal), 10진수(decimal)로 출력한다. |
skipws, noskipws | 입력할 파일을 열고 시작 지점부터 읽는다. |
ws | 스트림의 현재 위치부터 연달아 나온 공백 문자를 건너뛴다. |
get_money | 스트림에서 화폐 금액을 일정한 형식에 맞게 표현할 때 사용하는 매니퓰레이터로 인수를 받는다. |
get_time | 스트림에서 시간을 일정한 형식에 맞게 표현할 때 사용하는 매니퓰레이터로서 인수를 받는다. |
quoted | 지정한 스트링을 인용부호로 감싸고, 스트링 안에 있던 인용 부호를 이스케이프 문자로 변환한다. 이 매니퓰레이터도 인수를 받는다. |
setprecision | 분수값을 표현할 때 적용할 소수점 자릿수를 지정한다. 자릿수를 표현하는 인수를 받는다. |
setw | 숫자 데이터를 출력할 필드의 너비를 지정한다. |
setfill | 지정된 너비보다 숫자가 작을 때 빈 공간을 채울 문자를 지정한다. |
showpoint, noshowpoint | 소수점 아래의 수가 없는 부동소수점수를 스트림에 표현할 때 소수점의 표시 여부를 설정한다. |
4. 파일 스트림
파일은 스트림 개념과 정확히 일치한다. 파일을 읽고 쓸 때 항상 현재 위치를 추적하기 때문이다. C++파일 출력과 입력을 위해 ofstream, ifstream클래스를 제공한다. 둘 다 <fstream>헤더 파일에 정의돼 있다.
ios_base::app | 파일을 열고, 쓰기 연산을 수행하기 전에 파일 끝으로 간다. |
ios_base::ate | 파일을 열고, 즉시 파일 끝으로 간다. |
ios_base::binary | 입력 또는 출력을 텍스트가 아닌 바이너리 모드로 처리한다. |
ios_base::in | 입력할 파일을 열고 시작 지점부터 읽는다. |
ios_base::out | 출력할 파일을 열고 시작 지점부터 쓴다. 기존 데이터를 덮어쓴다. |
ios_base::trunc | 출력할 파일을 열고 기존 데이터를 모두 삭제한다. |
※ seek( ) tell( ) 메서드로 랜덤 액세스하기
입력과 출력 스트림은 모두 seek( )과 tell( ) 메서드를 갖고 있다.
seek | 입력 또는 출력 스트림에서 현재 위치를 원하는 지점으로 옮긴다. | seekg |
seekp | ||
tell | 스트림의 현재 위치를 알아낼 수 있다. 현재 위치를 streampos타입의 값으로 리턴한다. | tellg |
tellp |
- 여기서 g는 'get'을 p는 'put'을 의미한다. seek하나로 표현하지 않고 구분한 이유는 파일 스트림처럼 입력과 출력을 모두 가질 때가 있기 때문이다. 이럴 때는 읽는 위치와 쓰는 위치를 별도로 관리해야 한다. 이를 양방향(bidirectional)I/O라고 부른다. seekg와 seekp는 각각 두가지 버번이 있는데, 하나는 절대 위치를 나타내는 인수 하나만 받아서 그 위치로 이동한다. 다른 하나는 오프셋과 위치에 대한 인수를 받아서 지정한 위치를 기준으로 떨어진 거리(오프셋)로 이동한다. 이때 위치는 std::streampos로, 오프셋은 std::streamoff로 표현한다.
ios_base::beg | 스트림의 시작점 |
ios_base::end | 스트림의 끝점 |
ios_base::cur | 스트림의 현재 위치 |
※ 텍스트 모드와 바이너리 모드?
바이너리 모드로 열면 정확히 바이트 단위로 지정한 만큼만 파일에 쓴다. 파일을 읽을 때는 파일에서 읽은 바이트 수를 리턴한다. 텍스트 모드로 열면 파일에서 \n이 나올 때마다 한 줄씩 읽거나 쓴다. (파일에서 줄끝(EOL)을 나타내는 문자는 os마다 다르다. 윈도우는 \n이 아닌 \r\n으로 줄끝을 표현한다.)
5. 스트링 스트림
string에 스트림 개념을 추가한 것으로 텍스트 데이터를 메모리에서 스트림 형태로 표현하는 인메모리 스트림을 만들수 있다. 스트링 스트림은 기본적으로 토근화(tokenizing)기능을 제공하기 때문에 텍스트 구문 분석(파싱parsing)작업에 활용해도 편하다.
string에 데이터를 쓸 때는 std::ostringstream클래스를, 반대로 string에서 데이터를 읽은 때는 std::istringstream클래스를 사용한다. 둘다 <sstream>헤더 파일에 정의돼 있다. ostringstream과 istringstream은 각각 ostream과 istream을 상속하므로 기존 입출력 스트림처럼 다룰 수 있다.
표준 c++string만 사용하지 않고 스트링 스트림을 함께 활용하면 데이터를 읽거나 쓸 지점(현재 위치)을 알 수 있어서 좋다.
출처: 전문가를 위한 C++
'👨🏻💻 programming > ◽ c, c++' 카테고리의 다른 글
[C++] 제네릭 알고리즘 모음 (0) | 2022.05.16 |
---|---|
[C++] std::string_view 클래스 (0) | 2022.02.09 |
[C++] 연산자 오버로딩 프로토타입 & 한계 (0) | 2022.02.08 |
[C++] 비동기 프로그래밍 (0) | 2021.03.14 |
(c++) 조건 변수(Conditional Variable) (0) | 2021.03.13 |
안 하는 것 보다 낫겠지
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!