八、标准IO库
1. IO标准库
标准库:
头文件 类型
iostream istream, ostream, iostring从前两者派生而来
fstream ifstream, ofstream, fstream从iostream派生而来
sstream istringstream, ostringstream, stringstream从iostream派生而来
国际字符的支持: 在处理类前加“w”:wostream/wistream
IO对象不可复制或赋值(和继承有一定关系,后面说明):
如果需要传递或返回IO对象,则必须传递或返回指向该对象的指针或引用: ofstream &pring(ofstream &)
对IO对象的读写会改变其状态,因此引用必须是非const的。
条件状态:
badbit: 系统级故障、通常流不能再使用,此时 s.bad()返回true
failbit: 可恢复的错误 s.fail()返回true
eofbit:文件结束符,同时还设置了failbit s.eof()返回true
s.clear()将所有状态值都重设为有效;s.clear(flag)将某一个状态设置为有效,如flag = istream::fail, 则将错误输入取消;s.setstate(flag)设置状态;s.rdstate()返回当前状态,是strm::iostate类型
可以同时设置多个状态:is.setstate(ifstream:badbit | ifstream:failbit)
逗号操作符:计算每一个操作符,返回最右边操作数作为整个操作的结果:while(cin >> val, !cin.eof())
每个IO对象管理一个缓冲区,用于存储程序读写的数据,下面情况会刷新缓冲区:
1. 程序正常结束,清空所有缓冲区
2. 缓冲区已满,在写下一个值之前刷新
3. 用操作符如endl(插入一个新行、输出时应多用endl而不是\n)、ends(插入空字符null)、flush(不插入任何数据)显示刷新
4. 每次输出操作完了之后,用unitbuf操作符设置流的内部状态:
cout << unitbuf << "hello" << "world" << nounitbuf(重新变成缓冲区刷新方式);
以上等同于: cout << "hello" << flush << "world" << flush;
5. 将输出流与输入流关联(tie)起来,这时,在读输入流时将刷新其关联的输出缓冲区: cin与cout绑定在一起,因此cin >> val会导致cout相关的缓冲区被刷新;
cin.tie(0)会导致取消上述绑定,cin.tie(&cout)会重新绑定;
2. 文件输入与输出
ifstream、ofstream等fstream对象如果使用open或使用文件名作初始化式,需要传递的实参为C风格字符串,可通过string调用c_str成员函数:
ifstream infile(ifile.c_str());
ofstream outfile; outfile.open("out");
文件模式:
in 读操作、ifstream、fstream
out 写操作 ofstream、fstream
app 在写之前找到文件尾 ofstream、fstream
ate 打开文件后定位到文件尾 所有模式
trunc 打开文件时清空已存在文件流(同out) ofstream、fstream
binary 以二进制模式进行IO操作 所有模式
fstream inOut("copyOut", fstream::in | fstream::out),默认情况同时使用in out 模式,同时使用in与out模式,则不清空文件内容
fstream inOut("copyOut", fstream::in | fstream::out | fstream::trunc) 清空文件内容。
可直接通过判断infile、outfile的状态来判断打开文件是否成功。
在将文件流重新绑定到新的文件之前必须先将文件流关闭。调用close()成员函数。同时,需要调用clear()函数来清除原有的文件流状态,不调用clear则会保留上一次的文件流状态。如果上一次流出现错误或者已经读到文件的末尾,不清楚流的状态则不能继续使用该流。
3. 字符串流
stringstream strm(s) : s是string类型的对象
strm.str() : 返回存储的string类型对象
strm.str(s) : 将string类型的s复制给strm,返回void
处理输入:
string line, word;
while(getline(cin, line))
{
istringstream stream(line);
while(stream >> word){
//do operations
}
}
一般情况下,使用输入操作符读string时,空白符和换行符将会忽略。
int val1, val2;
string format("val1: 512\nval2: 1024");
istringstream strm(format);
string dump;
strm >> dump >> val1 >> dump >> val2;