由于继承巴拉巴拉的属性 (目前还没学到,以后再说) IO types 之间很像。比如后来支持的宽字符类型和专门处理宽字符的流,他们的用法跟窄字符的都一样的

No Copy or Assign for IO Objects

这看似是一个小知识点,但其实它蕴含了:

  • 不能将 IO types 作为函数的 para 和 return type
  • 使用 reference 传递和返回 IO
  • 由于每次的读写会改变 IO,所以也不能是 const

Condition States

Because a stream might be in an error state, code ordinarily should check whether a stream is okay before attempting to use it.

  • We can directly use that object as a conditon
  • or Interrogating the State of a Stream:

C++ Primer, p313

Buffer

buffer, which it uses to hold the data that the program reads and writes.

Because writing to a device can be time-consuming, 所以让操作系统去选择将一些输出暂存结合,再一起输出,这个过程叫 flush

There are several conditions that cause the buffer to be flushed:

  • 程序正常结束
  • 当 buffer 满了也会先 flush 一下
  • explicitly using manipulator such as endl
  • use the unitbuf manipulator to set the stream’s state, 这样就能每次输出都 flush。(By default, unitbuf is set for cerr)
  • the output stream is flushed whenever the stream to which it is tied is read or written. (By default, cin and cerr are both tied to cout. Hence, reading cin or writing to cerr flushes the buffer in cout)

这也告诉我们,以后我们也要让 input is tied to the output

cout << "hi!" << endl;  // writes hi and a newline, then flushes the buffer
cout << "hi!" << flush; // writes hi, then flushes the buffer; adds no data
cout << "hi!" << ends;  // writes hi and a null, then flushes the buffer
 
cout << unitbuf;   // all writes will be flushed immediately 
// any output is flushed immediately, no buffering 
cout << nounitbuf; // returns to normal buffering
 
cin.tie()       // returns a pointer to which this object is currently tied
cin.tie(&cout); // illustration only: the library ties cin and cout for us 
// old_tie points to the stream (if any) currently tied to cin 
ostream * old_tie = cin.tie(nullptr); // cin is no longer tied 
// ties cin and cerr; not a good idea because cin should be tied to cout 
cin.tie(&cerr);   // reading cin flushes cerr, not cout 
cin.tie(old_tie); // reestablish normal tie between cin and cout

tie 是单向的。i tie o, o tie o; but o tie i is wrong. 我想 是做了io去跟be tied的o说flush,反过来做了io也通知不到另一个o呀

Buffer Are Not Flushed If the Program Crashed

When a program crashes, it is likely that data the program wrote may be sitting in an output buffer waiting to be printed.

When you debug a program that has crashed, it is essential to make sure that any output you think should have been written was actually flushed.

Use cerr & cout, with Surperising Output

#include <iostream>
using namespace std;  
 
void f() { cerr << "f()" << endl; }  
void g() { cerr << "g()" << endl; }  
  
int main() {  
    f();  
    cout << endl << endl;  
    g();  
    return 0;  
}

当我反复运行的时候,那两条 errMsg 有时在上,有时在下,这是为什么?

stackoverflow上有一个类似的问题。总结起来就是,cerrcout 本就是两个不同的 stream,他们何时发生本就不确定

File Input and Output

string Stream