文章目录
- IO库类型和头文件
- IO对象无拷贝或赋值
- IO流的条件状态
- 文件输入输出
- ifstream 示例
- ofstream 示例
- 文件模式
- 以out模式打开文件会丢弃已有数据
- 每次调用open时都会确定文件模式
- ofstream 保留源文件 追加数据 示例
- string流
- istringstream示例
- ostringstream示例
IO库类型和头文件
为了支持不同种类的IO处理操作,标准库定义了一些IO类型。
iostream定义了用于读写流的基本类型。fstream定义了读写命名文件的类型。sstream定义了读写内存string对象的类型。
类型ifstream和istringstream都继承自istream,因此,我们可以像使用istream对象一样来使用ifstream和istringstream。
IO对象无拷贝或赋值
由于不能拷贝IO对象,因此我们也不能将形参或返回类型设置为流类型。进行IO操作的函数通常以引用方式传递和返回流。读写一个IO对象会改变其状态,因此传递和返回的引用不能是const的。
IO流的条件状态
一个流一旦发生错误,其上后续的IO操作都会失败。只有当一个流处于无错状态时,我们才可以从它读取数据,向它写入数据。由于流可能处于错误状态,因此代码通常应该在使用一个流之前检查它是否处于良好状态。确定一个流对象的状态的最简单的方法是将它当做一个条件使用。
badbit表示系统级错误,如不可恢复的读写错误。通常情况下,一旦badbit被置位,流就无法再使用了。在发生可恢复错误后,failbit被置位,如期望读取数值却读出一个字符等错误。这种问题通常是可以修正的,流还可以继续使用。如果到达文件结束位置,eofbit和failbit都会被置位。goodbit的值为0,表示流未发生错误。如果badbit、failbit和eofbit任一个被置位,则检测流状态的条件会失败。
文件输入输出
头文件fstream定义了三个类型来支持文件IO:ifstream从一个给定文件读取数据,ofstream向一个给定文件写入数据,以及fstream可以读写给定文件。
创建文件流对象时,我们可以提供文件名(可选的)。如果提供了一个文件名,则open成员函数会自动被调用,示例如下:
ifstream in(ifile); // 构造一个ifstream并打开给定文件ifile,在新c++标准中,文件名ifile既可以是库类型string对象,也可以是C风格字符数组
ofstream out; // 输出文件流未关联到任何文件
在要求使用基类型对象的地方,我们可以用继承类型的对象来替代。这意味着,接受一个iostream类型引用(或指针)参数的函数,可以用一个对应的fstream(或sstream)类型来调用。也就是说,如果有一个函数接受一个ostream&参数,我们在调用这个函数时,可以传递给它一个ofstream对象,对istream&和ifstream也是类似的。
流如果调用open失败,failbit会被置位。对一个已经打开的文件流调用open会失败,并会导致failbit被置位。随后的试图使用文件流的操作都会失败。为了将文件流关联到另外一个文件,必须首先关闭已经关联的文件。一旦文件成功关闭,我们就可以打开新的文件关联新的文件。
当一个fstream对象被销毁时,close会自动被调用。
ifstream 示例
打开string文件,按行存储元素,str即是每一行的string
ifstream in("text.txt");
string str;
getline(in,str);
将每一个单词作为一个独立的元素进行存储
ifstream in("text.txt");
string str;
in>>str;
ofstream 示例
ofstream ofs("test.txt");
ofs << "hello"<<" world"<<endl;
文件模式
每个流都有一个关联的文件模式,用来指出如何使用文件。
以out模式打开文件会丢弃已有数据
默认情况下,我们打开一个ofstream时,文件的内容会被丢弃。阻止一个ofstream清空给定文件内容的方法是同时指定app模式。
保留被ofstream打开的文件中已有数据的唯一方法是显式指定app或in模式。
每次调用open时都会确定文件模式
通常情况下,out模式意味着同时使用trunc模式,即当前文件内容将被清空。当指定app模式时,文件中的已有数据得以保留,所有写操作都在文件末尾进行。
ofstream 保留源文件 追加数据 示例
ofstream ofs("test.txt",ofstream::app);
ofs << "hello"<<" world"<<endl;
string流
sstream头文件定义了三个类型来支持内存IO,这些类型可以向string写入数据,从string读取数据,就像string是一个IO流一样。
istringstream从string读取数据,ostringstream向string写入数据,而头文件stringstream既可以从string读取数据也可以向string写入数据。
istringstream示例
以整行为元素读取文件,存入vector中,并用istringstream从vector中读取元素,每次读取一个单词
ifstream ifs("test.txt");string str;vector<string>vec;while (getline(ifs,str)) {vec.push_back(str);}for (auto a:vec) {istringstream vecStr(a);string tmp;while(vecStr >> tmp)cout << tmp<<endl;}
ostringstream示例
ostringstream os;
os << "hello" << " world" << endl;
cout << os.str();
此时界面上会显示hello world