1월 29, 2016

ch15. Input/Output using stream classes

0. Overview

  • C++11부터 string stream과 file stream이 rvalue와 move semantic을 지원.
순서



1. Background of I/O streams

  1. stream objects
  2. output : stream으로 흘러들어오는 데이터
    input : stream에서 흘러나가는 데이터

  3. stream classes
  4. class istream : 데이터를 읽는데 사용되는 input stream
    class ostream : 데이터를 쓰는데 사용되는 output stream

  5. global stream objects
    • cin
    • cout
    • cerr
    • clog
  6. stream operators
  7. manipulators
  8. stream을 조작하기 위해 사용되는 특수한 object. input을 읽어들이는 방식이나 output이 출력되는 방식을 바꾸는 유일한 방법임.

  9. a simple example


2. Fundamental stream classes and objects

  1. Classes and class hierarchy
  2. //rev header file including structure
    IOStream library는 철저히 각자의 책임을 분리하는 방향으로 설계됨. basic_ios를 상속받는 클래스들은 오직 formatting data만을 처리함. characters의 읽기와 쓰기는 basic_ios의 subobjects인 stream buffers에 의해 수행됨.

  3. Global stream objects
    • cin - istream
    • cout - ostream
    • cerr - ostream
    • clog - ostream
  4. Header files
  5. 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 되어있음.

  1. Output Operator <<
  2. C++11에서 같은 stream object를 concurrent output에 사용하는 것이 가능하지만 이 경우 출력이 서로 섞일 수 있음.

  3. Input Overator >>
  4. 두번째 param.는 non const value여야 함.
    C++11에서 같은 stream object를 concurrent input에 사용하는 것이 가능하지만 이 경우 입력이 서로 섞일 수 있음.

  5. Input/Output Of Special Types
    • Numeric type
    • input 읽을 때 적어도 한자리 숫자로 시작해야함. 그렇지 않으면 value는 0이 되고 failbit이 set 됨.

    • Type bool
    • false는 0으로, true는 1로 converting.

    • Types char and wchar_t
    • leading whitespace is skipped by default. whitespace까지 읽고 싶을 때는 flag _skipws_를 clear하거나 member function get()을 사용.

    • Type char *
    • 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 단위로 입력이 가능.

    • Type void *
    • void * 를 사용 시 pointer 출력(memory address 출력)도 가능.
      char * cstring = "hello"; std::cout << static_cast<void *>(cstring) << std::endl; // cstring의 주소가 출력됨
    • Stream Buffers
    • C++ I/O/ streams를 이용해서 파일을 복사하는 가장 빠른 방법. 15.14.3 참조.

    • User-Defined Types
    • Monetary and Time Values

4. State of Streams

Stream에는 I/O가 성공했는지 실패했는지, (실패한 경우) 실패한 이유 등이 기록된 state가 있음.

  1. Constants for the State of Streams
    • goodbit
    • eofbit
    • failbit
    • badbit

    flags는 class basic_ios 에 포함되어있기 때문에 class basic_istream 또는 class basic_ostream 의 모든 객체에 존재한다. 그러나 stream buffer는 아무런 state flag를 가지지 않는데, 이는 하나의 stream buffer 가 여러개의 stream 객체에서 사용될 수 있기 때문.

  2. Member Functions Accessing the State of Streams
  3. error bits는 언제나 명시적으로 clear 해줘야 함.

  4. Stream State and Boolean Conditions
  5. operator >> 의 default 설정은 leading whitespace를 skip함. 이런 whitespace skip을 막고 싶다면 stream member function의 put()과 get() 을 사용할 수 있으며, 이보다 나은 방법으로 istreambuf_iterator를 이용해 I/O 필터를 구현할 수도 있음.

    if ( !(std::cin >> x)) { // !뒤의 괄호 위치에 주의
    // the read failed
    ...
    }

  6. Stream State and Exceptions
  7. 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
  1. 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..

    그러나 C-strings를 읽을 때는 위의 함수들보다 operator >>를 사용하는 것이 더 안전함.
    character나 string을 읽을 때 istream member function을 사용하는 것보다 stream buffer를 통해 바로 접근하는 것이 더 유리할 때가 많은데, 이는 stream buffer member function은 input 과정에서 (istream class와 달리) sentry object를 생성하지 않아 construction overhead가 없기 때문.

  2. Example Uses
  3. sentry objects
  4. 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해야함.

  1. Overview of All Manipulators
    • endl
    • ends
    • flush
    • skipws
    • noskipws
    • setw
    • setfill
    • boolalpha
    • showpos
    • dec
    • hex
    • ...
  2. How Manipulators Work
  3. manipulator가 어떻게 작동할지는 구현하기에 따라서 달라지며, 구현 과정에 있어서 표준적인 방법은 존재하지 않음.

  4. User-Defined Manipulatrs

Formatting

  1. Format Flags
  2. Input/Output Format of Boolean Values
  3. Field width, Fill Character, and Adjustment
  4. Positive Sign and Uppercase Letters
  5. Numeric Base
  6. Foating-Point Notation
  7. General Formatting Definitions


출처

the c++ standard library a tutorial and reference by Nicolai M. Josuttis

댓글 없음:

댓글 쓰기