1.常用的IO库设施
istream类型,提供输入操作
ostream类型,提供输出操作
cin,一个istream对象,从标准输入读数据
cout,一个ostream对象,向标准输出写入数据
cerr,一个ostream对象,向标准错误写信息。
//>>:从一个istream对象读数据
//<<:向一个ostream对象写入数据
2.IO库类型和头文件
2.1.iostream头文件中包含类类型
用来读写流
istream,wistream,ostream,wostream,iostream,wiostream
2.2.fstream头文件中包含类类型
用来读写文件
ifstream,wifstream, ofstream, wofstream, fstream, wfstream
3.3.sstream头文件中包含类类型
用来读写string
istringstream,wistringstream,ostringstream,wostringstream,stringstream,wstringstream
3.对宽字符支持
标准库一开始只支持char类型,后来支持wchar_t(宽字符)类型
宽字符版本的函数和类型的名字以一个w开始,如wcin,wcout, wcerr.
宽字符版本的类型和对象与其普通char版本的类型定义在同一个头文件中。
本部分后面介绍的标准库流特性都可以无差别的应用于普通流,文件流,string流,以及char或宽字符流版本。
4.IO对象无拷贝或赋值。读写一个IO对象会改变其状态,因此传递和返回的引用不能是const的。
5.IO操作容易发生错误,一些错误是可恢复的,而其他错误则发生在系统深处,已经超出了应用程序可以修正的范围。
IO库条件状态:
strm指流类型,可以是普通流,文件流,string流及其正常,宽字符版本
strm::iostate iostate是一种机器相关的类型,提供了表达条件状态的完整功能。
strm::badbit 用来指出流已经崩溃
strm::failbit 用来指出一个IO操作失败了
strm::eofbit 用来指出流到达了文件结束
strm::goodbit 用来指出流未处于错误状态
s.eof() 若流s的eofbit置位,返回true
s.fail() 若流s的failbit置位,返回true
s.bad() 若流s的badbit置位,返回true
s.good() 若流s处于有效状态,返回true
s.clear() 将流s中所有条件状态位复位,将流的状态设置为有效,返回void。
s.clear(flags) 根据给定的flags标志位,将流s中对应的条件状态位复位。flags的类型为strm::iostate。返回void。作用和setstate一样?
s.setstate(flags) 根据给定的flags标志位,将流s中对应的条件状态为置位。flags的类型为strm::iostate。返回void
s.rdstate() 返回流的当前条件状态,返回值类型为strm::iostate
一个流一旦发生错误,其上后续的IO操作都会失败。只有当一个流处于无错状态时,才可从它读取数据,向它写入数据。
因此,代码通常在使用一个流之前检查它是否处于良好状态。确定一个流对象状态的最简单的方法是将它当作一个条件来使用。流保持有效状态时,条件运算结果是true。
badbit,表示系统级错误,
failbit,表示错误,如到达文件结束位置,期望和实际读取的类型不符等。发生系统级错误时,failbit也会被置位。
eofbit,表示到达文件结束位置
goodbit的值为0,表示流未发生错误。
如果badbit,failbit,eofbit中任一个被置位,则检测流状态的条件会失败。
6.输出缓冲区刷新
每个输出流都管理一个缓冲区,用来保存程序读写的数据。
有了缓冲机制,操作系统可以将程序的多个输出操作组合成单一的系统级写操作。由于设备的写操作耗时,允许操作系统将多个输出操作组合为单一的设备写操作可以带来很大的性能提升。
导致缓冲刷新(即,数据真正写入到输出设备或文件)的原因有很多:
a.程序正常结束,作为main函数return操作一部分。缓冲刷新被执行。
b.缓冲区满时,需要刷新缓冲,而后新的数据才能继续写入缓冲区。
b.可使用操作符如endl来显示刷新缓冲区。
d.在每个输出操作后,我们可以用操纵符unitbuf设置流的内部状态,来清空缓冲区。默认下,对cerr是设置unitbuf的,因此写到cerr的内容是立即刷新的。
e.一个输出流可能被关联到另一个流。这种情况下,当读写被关联的流时,关联到的流的缓冲区会被刷新。如默认下,cin,cerr都关联到cout,因此,读cin或写cerr都会导致cout的缓冲区被刷新。
endl,完成换行并刷新缓冲区的工作。
flush,刷新缓冲区,不输出额外字符。
ends,向缓冲区插入一个空字符,然后刷新缓冲区。
//cout<<“hi”<<endl;
//cout<<“hi”<<ends;
//cout<<“hi”<<flush;
如希望在每次输出操作后都刷新缓冲区,可以使用unitbuf操纵符。它告诉流接下来每次写操作后都进行一次flush操作。nounitbuf操纵符则重置流,使其恢复使用正常的系统管理的缓冲区刷新机制。
// cout << unitbuf; 此后所有输出操作后会立即刷新缓冲区
// cout << nounitbuf; 回到正常的缓冲方式
程序异常终止时,输出缓冲区不会被刷新。
当一个输入流被关联到一个输出流时,任何从输入流读取数据的操作都会先刷新关联的输出流。标准库的cout和cin是关联的。
对流对象可以用tie实现关联
strm.tie() // 返回指向本流对象关联到的一个输出流的指针
strm.tie(&ostrm) // 将流对象strm关联到ostrm
7.文件流
fstream,ifstream,ofstream // 读取、写入、读写
7.1.文件流特有操作:
fstream fstrm; //创建一个未绑定的文件流。fstream是一个类型
fstream fstrm(s)//创建一个fstream,并打开名为s的文件
fstream fstrm(s,mode)//与前一个相似,但按指定mode打开文件
fstrm.open(s); // 打开名为s的文件
fstrm.close();//关闭
fstrm.is_open(); // 返回一个bool值,指出一个fstrm关联的文件是否成功打开且尚未关闭
接收一个iostream类型引用或指针参数的函数,可以用一个对应的fstream或sstream类型来调用。
如果 文件流open失败,failbit会被置位。open成功,会设置流的状态,使good()为true。。
当一个fstream对象被销毁时,close会自动被调用。
7.2.文件模式
文件模式
in 以读方式打开 // 只对ifstream,fstream有效
out 以写方式打开// 只对ofstream,fstream有效
app 每次写操作前都定位到文件末尾//不能和trunc连用,app下默认是out
ate 打开文件后立即定位到文件末尾 // 任何类型
trunc 截断文件//只有已指定out时,有效
binary 以二进制方式进行IO //任何类型
fstream fstrm(s,mode)
ofstream out (“filel”,ofstream::out | ofstream::trunc);//out隐含后面的两项
ofstream app(“file2”,ofstream::out | ofstream::app)
默认下out方式打开ofstream或fstream对象时,采用trunc。若指定了app或in,没有trunc效果。ate和binary对文件流对象都适用。
8.string流
stringstream特有操作
sstream strm;
sstream strm(s); // strm保存一个string s的拷贝。
strm.str(); // 返回strm保存的string的拷贝。
strm.str(s); // 把string s拷贝到strm中。
当我们的某些工作是对整行文本进行处理,而其他工作是处理行内的单个单词的时候可以使用;
struct PersonInfo
{
string name;
vector phones;
}
string line,word;
vector 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);
}
for(const auto &entry:people)
{
ostringstream formatted, badNums;
for (const auto &nums:entry.phones){
if (!valid(nums)){
badNums << “ ”<<nums;
}else
formatted << “ ”<<format(nums);
}
if (baiNums.str().empty())
os <<entry.name<<” ”<<formatted.str()<<endl;
else
cerr<<”input error: ”<<entry.name<<”invalid number(s) ”<<badNums.str()<<endl;
9.标准库流分析
优势是简单,易用,可见到源码。
以后尝试多用标准库流实现IO控制,减少使用Windows文件API。
使用标准库的东西直接看相应源码替代看书,直接看源码,就是最好的了解学习。