1. 标准IO库
标准库定义了一族类型,支持对文件和控制窗口等设备的读写,还使得string对象能够像文件一样操作。采用继承来实现。
流:是以字节方式对数据从源到目标进行传递的一种描述。
输入流:指从输入设备到内存中字节的传递;
输出流:指从内存到输出设备中字节的传递;
iostream类库的接口对应的头文件:
头文件iostream包含所有i/o流所需的基本信息,并定义有四个标准i/o流对象:
cin:标准输入流对象(与标准输入设备连接)
cout :标准输出流(与标准输出设备连接)
cerr :非缓冲的标准错误流(默认设备为显示器)
clog :经缓冲的标准错误流(默认设备为打印机)
2. IO对象不可复制或者赋值:
准库类型不允许做复制或者赋值操作。这个要求说明:
首先,在流对象不能在容器类型(如vector)中储存,因为容器类型中只能储存支持复制的元素类型。
其次,形参或者返回类型不能为流类型。如果非要传递或者返回IO对象,那么必须传递或返回指向该对象的指针或者引用。
3. 条件状态:IO标准库管理一系列的条件状态,用来标记给定的IO对象是否处于可用状态。
流必须处于无错误状态,才可以用于输入或者输出。检查流是否可用的最简单方法是检查它的真值:
<span style="font-size:18px;">if(cin)
while(cin>>word)</span>
4. IO标准库的条件状态:
strm::iostate 由各个iostream 类定义,用于定义条件状态
strm::badbit strm::iostate类型的值,用于指出被破坏的流
strm::failbit strm::iostate类型的值,用于指出失败的IO操作
strm::eofbit strm::iostate类型的值,用于指出流已经到达文件的结束符
s.eof() 如果设置了流s的eofbit值,该函数返回true
s.bad() 如果设置了流s的badbit值,该函数返回true
s.fail() 如果设置了流s的failbit值,该函数返回true
s.good() 如果流s处于有效状态,该函数返回true
s.clear() 清空流s的所有状态,并设为true
s.clear(flag) 给流s的某个条件状态位设置为true。flag,类型是strm::iostate
s.setstate(flag)给流s的添加指定条件。flag,类型是strm::iostate
s.rdstate() 返回流s的当前条件,返回值类型是strm::iostate
5. 流状态的查询和控制:
<span style="font-size:14px;">int ival;
while(cin>>ival,!cin.eof())//逗号操作符,首先计算它的每一个操作数,然后返回最右边的操作数作为整个操作的结果。
{
if(cin.bad())
/*do something*/
if(cin.fail())
{
cerr<<”bad data”;
cin.clear(istrea::failbit);
continue;
}
}</span>
6. 输出缓冲区的管理:
每个IO对象管理一个缓冲区,用于存储程序读写的数据。
os<<”please”;
系统将字符串字面值存储在与流os相关的缓冲区中。下面几种情况将导致缓冲区的内容被刷新,即写入到真实的输出设备或者文件。
(1)程序正常结束,作为main的返回工作的一部分,将清空所有的输出缓冲区。
(2)在一些不确定的时候,缓冲区可能已经满了,此时,缓冲区将会在写下一个值之前刷新。
(3)用操纵符显示的地刷新,如endl,flush,ends.
(4)每次输出操作执行完成后,用unitbuf操纵符设置流的内部状态,从而清空缓冲区
(5)将输出流与输入流关联(tie)起来,此时,在读输入流时将刷新其关联的输出缓冲区。
7. 文件的输入和输出:
程序如果要读写控制窗口,那么采用标准库定义的对象cin,cout,cerr。
程序如果要读写文件,需要自行定义对象,然后将它们绑定到问价上。
注意小心,如果需要重用文件流读写多个文件,那么必须在读另一个文件之前调用clear()清除该流的状态,然后再close()。否则,可能上个对象的错误状态仍然残留在新的对象那个那里。
8.文件模式:
in, out, app, ate, trunk, binary
9.字符串流使用举例:
<span style="font-size:14px;">while(getline(cin,line))
{
istringstream stream(line);
<span style="white-space:pre"> </span> while(stream>>word)
{...}
}</span>
10.文件流概述
使用:文件流对象>>变量1>>变量2>>…;完成读操作;
使用:文件流对象<<表达式1>>表达式2>>…;完成写操作;
<span style="font-size:14px;"> #include <fstream> //包含文件流类头文件
int main()
{
ofstream out; //定义输出流对象
out.open(“AAA”); //打开文件
if(!out) //文件打开失败,out值为假
{
cout << "Cannot open AAA file./n";
return 1;
}
out << "C++ " << 89.5 << endl;
out << "English " << 93.5 << endl;
out << "Maths " << 87 << endl;
out.close(); //关闭文件
}</span>
类比理解文件读写操作
就像cout是标准读写操作的输出对象一样,文件读写操作中的输出流对象是out.
就像标准读写操作的显示目的地为显示屏,文件读写操作中的显示目的地为文件。
那么,既然为文件的话,肯定需要一行代码区指明文件名称。那么out和文件名称也就成了一套搭配工作的工具,一起把内存中的数据写入文件。
所以,一开始,需要定义ofstream的对象,也需要把这个具体的对象和一个具体的文件关联起来。