0. Overview
- C++11부터 string stream과 file stream이 rvalue와 move semantic을 지원.
- 1. Background of I/O streams
- 2. Fundamental stream classes and objects
- 3. Standard Stream Operators << and >>
- 4. State of Streams
- 5. Standard Input/Output Functions
- 6. Manipulators
- 7. Formatting
1. Background of I/O streams
- stream objects
- stream classes
- global stream objects
- cin
- cout
- cerr
- clog
- stream operators
- manipulators
- a simple example
output : stream으로 흘러들어오는 데이터
input : stream에서 흘러나가는 데이터
class istream : 데이터를 읽는데 사용되는 input stream
class ostream : 데이터를 쓰는데 사용되는 output stream
stream을 조작하기 위해 사용되는 특수한 object. input을 읽어들이는 방식이나 output이 출력되는 방식을 바꾸는 유일한 방법임.
2. Fundamental stream classes and objects
- Classes and class hierarchy
- Global stream objects
- cin - istream
- cout - ostream
- cerr - ostream
- clog - ostream
- Header files
//rev header file including structure
IOStream library는 철저히 각자의 책임을 분리하는 방향으로 설계됨. basic_ios를
상속받는 클래스들은 오직 formatting data만을 처리함. characters의 읽기와 쓰기는
basic_ios의 subobjects인 stream buffers에 의해 수행됨.
application programmer는 <iosfwd>를 include하는 것으로 충분하며,
input, output functions을 사용하기 위해 필요에 따락 각각
<istream>과 <ostream>을 include한다.
일반적으로 헤더 파일에는 꼭 필요한 파일만 include 한다. 특히 헤더파일에는 <iosfwd>만
include하고, 이에 대응되는 implementation 파일에 헤더 파일을 include해서 완전한 정의를
하도록 한다.
3. Standard Stream Operators << and >>
bit shift 연산자인 <<와 >>를 overloading 하여 입출력 연산자로 사용. void와 nullptr_t을 제외한 거의 모든 data type에 대해 overloading 되어있음.
- Output Operator <<
- Input Overator >>
- Input/Output Of Special Types
- Numeric type
- Type bool
- Types char and wchar_t
- Type char *
- Type void * void * 를 사용 시 pointer 출력(memory address 출력)도 가능.
- Stream Buffers
- User-Defined Types
- Monetary and Time Values
C++11에서 같은 stream object를 concurrent output에 사용하는 것이 가능하지만 이 경우 출력이 서로 섞일 수 있음.
두번째 param.는 non const value여야 함.
C++11에서 같은 stream object를 concurrent input에 사용하는 것이 가능하지만 이 경우 입력이 서로 섞일 수 있음.
input 읽을 때 적어도 한자리 숫자로 시작해야함. 그렇지 않으면 value는 0이 되고 failbit이 set 됨.
false는 0으로, true는 1로 converting.
leading whitespace is skipped by default. whitespace까지 읽고 싶을 때는 flag _skipws_를 clear하거나 member function get()을 사용.
read wordwisely. leading whitespace is skipped by default. 다음 whitespace 나 end-of-file을 만날 때까지 읽음. flag _skipws_를 통해 leading whitespace를 skip할지 정할 수 있음. 만약 읽을 문자의 숫자를 지정하고 싶다면 setw(..) 를 사용.
char buffer[81]; std::cin >> std::setw(81) >> buffer;char * 를 사용하기보다 std::string 을 사용할 것을 권장. 이 경우 getline()을 통해 line 단위로 입력이 가능.
char * cstring = "hello"; std::cout << static_cast<void *>(cstring) << std::endl; // cstring의 주소가 출력됨
C++ I/O/ streams를 이용해서 파일을 복사하는 가장 빠른 방법. 15.14.3 참조.
4. State of Streams
Stream에는 I/O가 성공했는지 실패했는지, (실패한 경우) 실패한 이유 등이 기록된 state가 있음.
- Constants for the State of Streams
- goodbit
- eofbit
- failbit
- badbit
- Member Functions Accessing the State of Streams
- Stream State and Boolean Conditions
- Stream State and Exceptions
flags는 class basic_ios 에 포함되어있기 때문에 class basic_istream 또는 class basic_ostream 의 모든 객체에 존재한다. 그러나 stream buffer는 아무런 state flag를 가지지 않는데, 이는 하나의 stream buffer 가 여러개의 stream 객체에서 사용될 수 있기 때문.
error bits는 언제나 명시적으로 clear 해줘야 함.
operator >> 의 default 설정은 leading whitespace를 skip함. 이런 whitespace skip을 막고 싶다면 stream member function의 put()과 get() 을 사용할 수 있으며, 이보다 나은 방법으로 istreambuf_iterator를 이용해 I/O 필터를 구현할 수도 있음.
if ( !(std::cin >> x)) { // !뒤의 괄호 위치에 주의
// the read failed
...
}
backward compatibility를 위해 stream는 exception을 던지지 않는 것이 default로 설정되있지만, 모든 flag에 대해 flag가 set 되었을 때 exception을 던지게 설정할 수 있음.
exception은 보다 더 unexpectied situation에서 사용되어야 함. input/output 과정에서의 format error와 같은 error는 정상으로 간주되며, exception 처리 보다는 state flag를 통한 처리 방법이 더 좋은 방법임.
5. Standard Input/Output Functions
formatted operator | unformatted operator |
---|---|
<< / >> | get(..), getline(..), read(..) put(..), write(..) |
skips whitespaces | never skips leading whitespaces |
- Member functions for input
- get(c, num)
- get(c, num, t)
- getline(str, num)
- getline(str, num, t)
- read(str, num)
- readwome(str, num)
- etc..
- Example Uses
- sentry objects
그러나 C-strings를 읽을 때는 위의 함수들보다 operator >>를 사용하는 것이 더 안전함.
character나 string을 읽을 때 istream member function을 사용하는 것보다 stream buffer를 통해 바로 접근하는 것이 더 유리할 때가 많은데, 이는 stream buffer member function은 input 과정에서 (istream class와 달리) sentry object를 생성하지 않아 construction overhead가 없기 때문.
I/O stream operators 와 functions에서 I/O는 I/O preprocessing, 실제 I/O 작업, I/O postprocessing의 3단계에 걸쳐 수행됨. sentry class는 이를 위한 보조 클래스의 일종으로, stream과 관련된 여러 state에 관한 정보를 담고 있음. 만약 I/O operator를 stream buffer에 바로 적용하기 위해선 sentry object를 먼저 생성해줘야 함.
Manipuators
Manipulator for streams는 standard I/O operators에 적용되어 stream의 특성을 바꿔주는 object를 말함. arguments를 가지는 standard manipulators는 헤더파일 <iomanip>에 정의되어 있으며, 이를 사용하기 위해선 이 헤더 파일을 include해야함.
- Overview of All Manipulators
- endl
- ends
- flush
- skipws
- noskipws
- setw
- setfill
- boolalpha
- showpos
- dec
- hex
- ...
- How Manipulators Work
- User-Defined Manipulatrs
manipulator가 어떻게 작동할지는 구현하기에 따라서 달라지며, 구현 과정에 있어서 표준적인 방법은 존재하지 않음.
Formatting
- Format Flags
- Input/Output Format of Boolean Values
- Field width, Fill Character, and Adjustment
- Positive Sign and Uppercase Letters
- Numeric Base
- Foating-Point Notation
- General Formatting Definitions