笔记会持续更新,有错误的地方欢迎指正,谢谢!
第二部分 C++标准库
随着C++版本的一次次修订,标准库也越来越强大,
什么叫标准库呢?其实就是很多容器类和一族泛型算法(别急,后面章节会讲到),这些能帮我们编写简洁高效的程序,我们只需把精力放在求解问题上。
IO库
C++是通过标准库中的IO库来处理输入输出的,就是cin之类的东东。
别以为这章很简单,可是有大学问的,好好学吧~
IO类继承机制:
ifstream和istringstream继承自istream,ofstream和ostringstream都继承自ostream。只要记住我们怎么用istream,就怎么用其他两个;同理,只要记住我们怎么用ostream,就怎么用其他两个。
IO对象无拷贝或赋值
IO对象无拷贝或赋值:IO操作的函数通常以引用方式 传递 和 返回 流;由于读写会改变状态,IO对象的引用不能是const。
条件状态
代码通常应该在使用一个流之前检查它是否处于良好状态,比较简单的做法是把它当作条件:
int a;
while(cin >> a)
{
//执行操作部分
}
条件状态:
iostate表示流状态的类型,其包含4种constexpr值,badbit(流崩溃)、failbit(可恢复错误)、goodbit、eofbit;对应4个函数bad()、fail()、good()、eof()。
管理条件状态:
rdstate()获取状态,clear()清除所有错误标志位,clear(flags)和setstate(flags)将状态置为flags。
管理输出缓冲
文本串可能立即打印,也可能被操作系统保存在缓冲区中随后再打印。有了这么一个缓冲机制,操作系统就可以将程序的多个输出操作组合成单一的系统级写操作。
(前面我们讲过部分导致缓冲刷新的原因,现在完整地讲一次!)
导致缓冲刷新(就是数据真正写到输出设备或文件中)的原因有很多:
- 程序正常结束,作为main函数的return操作的一部分,缓冲刷新被执行;
- 缓冲区满了,所以要刷新缓冲,以便后来的数据能继续写入缓冲;
- 使用例如endl的操作符来显式刷新缓冲区;
- 在每个输出操作后,我们可以用unitbuf设置流的内部状态来清空缓冲区。并且,对于cerr来说,unitbuf是默认设置的,因此写到cerr的内容都是立即刷新的;
- 一个输出流关联到另一个流时,当读写其关联的流时,此输出流的缓冲区会自动刷新。例如,默认情况下,cin和cerr都关联到cout,因此读cin或者写cerr都会导致cout的缓冲区被刷新。(读是指输入,写是指输出。)
总结:每个流同时最多关联到一个流,但一个ostream可以同时被多个流关联。
刷新输出缓冲区:
有三个显式刷新的符:
cout << "你爷" << endl;
//输出你爷和换行,然后刷新缓冲区。cout << "你爸" << flush;
//输出你爸,然后刷新缓冲区。cout << "你伯" << ends;
//输出你伯和一个空字符,然后刷新缓冲区。
刷新缓冲区神器:开启unitbuf每次调用flush,nounitbuf解除:
看代码就懂:
cout << unitbuf;//接下来的所有输出都立即刷新,无缓冲
cout << nounitbuf //恢复正常的缓冲方式
关联输入和输出流
cin >> a;
//这句话会刷新缓冲区,因为标准库将cout和cin关联起来,所以从cin中读取数据会刷新cout缓冲区。
这是系统设置的关联流,如何自己设置关联流?不讲了,我没兴趣,你有兴趣的话,自己探索吧~