在操作系统中,i/o是对输入input/输出output的简称。输入输出在计算机中是以流的数据形式进行的。术语“流”(stream)想要表达的是,随着时间的推移,字符是顺序生成或消耗的。流(stream)是一个有方向的二进制串,其只能在一端生成一端消耗;C++使用标准库定义的各种IO类型对设备进行I/O。I/O类型有常用的有以下几个头文件:iostream(基本输入输出)、fstream(文件输入输出)、sstream(对string读取或写入)。
io类型不支持拷贝或赋值,因为会导致多个对象绑定同一个输入输出窗口,同时读写而发生错误。io类型传参应使用io的引用。
一、iostream,定义了用于读写流的基本类型 :
- iostream定义了4个标准io对象:
- cin(发音see-in) 标准输入,是一个istream类型的对象;
- cout(发音see-out) 标准输出,一个ostream类型的对象;
- cerr(发音see-error) 标准错误,用于输出警告的错误消息;
- clog(发音see-log) 用于输出程序运行时的一般信息;
系统通常将这些对象与程序运行窗口关联,当我们使用cin时,将从程序运行的窗口读入,当我们向cout、cerr和clog写入数据时,将会写到同一个窗口。以上是处理char字符的类型,对于宽字符类型(wchar_t)有wistream/wostream/wstream类型。
- 输入输出运算符:
- >> :输入运算符,接受一个istream对象作为左侧运算对象,接受一个对象作为其右侧运算对象,将istream对象中的内容输入到右侧运算对象中,运算结果仍是一个istream对象,所以 cin >> a >> b 成立。
- << : 输出运算符,接受一个ostream对象作为其右侧运算对象,接受一个对象作为其左侧运算对象,将左侧对象的内容输出到右侧的ostream对象中,运算结果仍是一个ostream对象,所以 cout << a << b 也成立。
- endl :cout << endl 常常被用于打印一个换行,实际上endl是一个操作符,它的效果是结束当前行并将与设备关联的缓冲区的内容刷到设备中。它可以保证缓冲区中的所有内容都被写入输出流。使用cout调试程序时应该保证一直endl刷新缓冲区,以使程序在崩溃时不会有数据仍在缓冲区中而引发错误。
- getline(istream, string):从一个给定的istream中读取一行,存入给定的一个string对象中。
二、io类型的检测标志:
io类型定义了一些函数和标志,可以帮助访问和操作流的条件状态,用于检测io操作是否正常执行。
io类型的四个条件状态的标志和一个表示条件状态的类型:
iostate | 一种机器相关的类型,是以下4种IO状态的位集合。IO库定义了4个constexpr值,表示特定的位模式。可以与位运算符一起使用来检测或设置多个标志。 |
badbit | 用于指出流已崩溃,表示系统级错误,通常被置位时,流已经不适合继续使用。 |
failbit | 用于指出一个I/O操作失败了。表示可以被修正的错误,如:读入一个无效输入;当到达文件结束位置时,failbit和eofbit都会被置位。 |
eofbit | 用于指出文件已到达结束位置, 即到达文件结束位置时置位。 |
goodbit | 用于指出流未处于错误状态,流正常运行时值为0,当badbit/failbit/eofbit任何一个被置位,goodbit也会被置位。 |
io类型的八个置位与检测函数:(作为成员函数被定义,使用方式:io对象.函数名() )
eof() | eofbit被置位则返回true,表示流已结束 |
fail() | failbit或badbit被置位,返回true:即发生了错误或io已结束就置位 |
bad() | badbit被置位,返回true,表示流已崩溃 |
good() | 若流有效(所有错误状态都未发生时),返回true |
clear(flags) | 按flags(iostate类型的对象)的内容复位流状态,并置流为有效状态,返回void |
setstate(flags) | 按flags内容置位流状态。返回void |
rdstate() | 返回一个表示当前流状态的iostate |
将输入输入流作为条件使用时,相当于使用 :!fail() 。
可以这样使用rdstate、clear和setstate:
每个输入流都管理一个缓冲区,用于保存程序的读写数据:
缓冲区刷新的三种情况:
1、main的return操作使缓冲区刷新;
2、缓冲区满,刷新缓冲区;
3、endl操作符 显式刷新缓冲区;
缓冲区操作符:
flush:刷新缓冲区,不输出任何字符;
ends:插入一个空格后,刷新缓冲区;
endl:插入一个换行符后,刷新缓冲区;
unitbuf操作符:设置每次输出都立即刷新缓冲区,使用方式: cout << unitbuf ;它的意思是每次写都执行flush操作。 nounitbuf操作符: 表示回到正常缓冲方式:cout << nounitbuf;
关联输入流和输出流:
当一个输入流被关联到一个输出流时,任何输入流的读取数据操作都会刷新关联的输出流,标准库将cout和cin关联,因此cin >> ival 会导致cout的缓冲区被刷新。
tie(ostream*) :设置istream或ostream对象关联的输出流,接受一个输出流的指针,若未给定输出流,返回当前关联的输出流指针,若未指定输出流也无关联的输出流,返回空指针。每个流最多关联一个输出流,但一个输出流可以被多个流关联。