1. <iostream>
2. <fstream>
3. <sstream>
为了支持宽字符语言,定义了一组类型和对象可以操作 wchar_t 类型的数据。宽字符版本的类型和函数名字以一个 w 开始。
类型之间关系:ifstream 和 istringstream 均继承自 istream。
IO 对象无拷贝和赋值,因此也无法将 IO 对象设为形参和返回值。
badbit 置位后流不可用,通常为系统级错误,如不可恢复的读写。failedbit 置位表示当前读写操作失败,流可能可以继续使用。
可以使用以下函数获取流的状态:
s.eof(); //是否到达文件结束。
s.failed(); //failedbit或badbit置位时返回true。
s.bad(); //badbit置位时返回true。
s.good(); //流有效时返回true。
判断一个流是否有效的最简单的方法是将其作为一个条件使用。
while(cin>>word)
//do something
这句话的含义是若流输 word 操作成功且之后流处于有效状态,返回 true。
此外,对于流的状态,还可以进行读取和设置。
s.clear(); //将流中所有状态标志复位,流置为有效。
s.clear(flags); //将指定状态位复位,flags类型为strm::iostate。
s.setstate(flags); //根据指定的flags标志位,将流对应的条件状态置位。
s.rdstate(); //返回当前流的状态,返回类型为strm::iostate。
例如:以下代码将 failbit 和 badbit 复位,保持其他标志位不变。
s.clear(cin.rdstate() & ~cin.failedbit & ~cin.badbit);
//failedbit和badbit从位上来看就是相应bit置1,其余bit全0的数
每个输出流都有一个缓冲区,用来保存程序读写的数据。
导致输出缓冲刷新的原因有很多:
cout<<unitbuf;
。取消则为:cout << nonunitbuf;
可以使用 tie 函数关联输入输出流,通常在交互式系统中比较常用,返回值是执行之前该流关联的流。
cin.tie(&cout);
ostream* old_tie = cin.tie(nullptr);
cin.tie(&cerr);
cin.tie(old_tie);
创建文件流对象时,我们可以选择提供文件名也可以不提供。区别是提供文件名后 open 函数会被自动调用。
ifstream in(infile); //infile可为string类型或c风格字符串
ofstream out;
open 主要作用是将流与文件建立关联。
若 open 失败则 failedbit 会被置位,对一个已经 open 的流再 open 也会导致失败。若 open 成功会设置流的状态,使得 good()变为 true。
ifstream in(file1);
//下面两行代码与上面一句等价
ifstream in;
in.open(file1);
close()为关闭文件与流的关联,close 后的流可以关联新的文件。
in.close();
in.open(ifile+"2");
fstream 对象拥有自动构造和析构的功能。
当 stream 对象离开其作用域后,会自动调用 close()函数并销毁对象。如,考虑一个程序,main 函数会接受一个处理文件的列表,可能会产生如下循环。
for(auto p = argv + 1 ;p < argv+argc; ++p){
ifstream in(*p);
if(in){
//do someting
}else
cerr << "can not open: " + string(*p);
} //每个循环in都会离开其作用域被销毁,并在下一个循环被重新创建。
文件模式及其意义:
文件模式 | 意义 |
---|---|
in | 以只读方式打开 |
out | 以只写形式打开 |
app | 每次写操作前定位到文件末尾 |
ate | 打开文件后立刻定位到文件末尾 |
trunc | 截断文件 |
binary | 以二进制方式进行 IO |
Tips:
ofstream out("file1",ofstream::app);
stringstream strm(s); //构造函数,传入的参数为string
strm.str(); //返回strm保存的string的拷贝
strm.str(s); //将string s拷贝到strm中,返回值为void
istringstream 常用于对整行数据进行处理。如,对于以下统计电话号码的程序,输入格式为:
morgan 77712173 82738888
lee 45663211
drew 66678321 12002919 12334556
由于每个人的号码数目并不相同,可以对于每一行进行处理,建立以下程序:
struct PersonInfo{
string name;
vector<string> phones;
}
string line,word;
vector<PersonInfo> people;
while(getline(cin,line)){
PersonInfo info;
istringstream record(line);
record>>info.name;
while(record>>word)
info.phones.push_back(word);
people.push_back(info);
}
多用于逐步构造输出,最后一起打印的情况。
例如统计以上电话号码数目非法与合法的情况,可以定义两个 ostringstream 对象,分别写入合法和非法的字符,最后通过 oss.str()即可获得字符串内容。