本篇总结 C++ 的文本操作,即C++文件和流的概念。
文件流
到目前为止,我们使用了iostream标准库,它提供了cin 和 cout 方法分别用于从标准输入读取流和向标准输入写入流。
如何从标准输入读取流和向标准输入写入流?这就需要用到 C++ 中另一个标准库fstream,它定义了三个新的数据类型:
数据类型 | 描述 |
---|---|
ofstream | 该数据类型表示输出文件流,用于创建文件并向文件写入信息 |
ifstream | 该数据类型表示输入文件流,用于从文件读取信息 |
fstream | 该数据类型通常表示文件流,且同时具有 ofstream 和 ifstream 两种功能,这意味着它可以创建文件,向文件写入信息,从文件读取信息。 |
要在C++中进行文件处理,必须在 C++ 代码中包含头文件 <iostream>
和 <fstream>
打开文件
在从文件读取信息或者向文件写入信息之前,必须先打开文件。ofstream 和 fstream对象都可以用来打开文件进行写操作;如果只需要打开文件进行读操作,则使用 ifstream 对象。
下面是open()函数的标准语法。
1 | void open(const char *fileName, ios::openmode mode); |
在这里,open()成员函数的第一参数指定要打开的文件名字,第二个参数指定打开文件的模式。
模式标志 | 描述 |
---|---|
ios::app | 追加模式,所有写入都追加到文件末尾 |
ios::ate | 文件打开后将文件指针位置定位到文件末尾 |
ios::in | 打开文件用于读取 |
ios::out | 打开文件用于写入 |
ios::trunc | 如果该文件已经存在,其内容将在打开之前被截断,即把文件长度设为0. |
可以把以上两种或两种以上的模式结合使用,以“或”运算(“|”)的方式。例如:如果想要以写入模式打开文件,并希望截断文件,以防文件已经存在,那么可以使用下面的语法:
1 | ofstream outFile; |
类似的,如果想要打开一个文件用于读写,可以使用下面的语法:
1 | ifstream afile; |
很多程序中,可能会碰到ofstream out(“Hello.txt”), ifstream in(“…”),fstream foi(“…”)这样的的使用,并没有显式的去调用open()函数就进行文件的操作,直接调用了其默认的打开方式,因为在stream类的构造函数中调用了open()函数,并拥有同样的构造函数,所以在这里可以直接使用流对象进行文件的操作,默认方式如下:
1 | ofstream out("...", ios::out); |
关闭文件
使用close() 函数关闭打开的文件,它是 fstream,ifstream 和 ofstream 对象的一个成员。
写入文件
我们使用 流插入运算符( << )向文件写入信息。
读取文件
我们使用 流提取运算符( >> )从文件读取信息。
例子
下面给出一个例子,读取hello.txt文件中的字符串,写入out.txt中:
1 |
|
其中getline(stream, string)函数的功能:按行从输入流中读入字符,存到string变量
直到出现以下情况为止:
读入了文件结束标志
读到一个新行
达到字符串的最大长度
如果getline()没有读入字符,将返回false,可用于判断文件是否结束。
1 | int v, w, weight; |
上述代码的功能是读取data.txt文件的数据,注意,此时要求data.txt文件中的数据是三个一行,每个数据用空格或换行符隔开。
文件指针
文件指针位置在c++中的用法:
标准 | 描述 |
---|---|
ios::beg | 文件头 |
ios::end | 文件尾 |
ios::cur | 当前位置 |
例如:
1 | file.seekg(0,ios::beg); //让文件指针定位到文件开头 |
注意:移动的单位是字节,而不是行。
状态标志符的验证(Verification of state flags)
除了eof()以外,还有一些验证流的状态的成员函数(所有都返回bool型返回值):
bad()
如果在读写过程中出错,返回 true 。例如:当我们要对一个不是打开为写状态的文件进行写入时,或者我们要写入的设备没有剩余空间的时候。
fail()
除了与bad() 同样的情况下会返回 true 以外,加上格式错误时也返回true ,例如当想要读入一个整数,而获得了一个字母的时候。
eof()
如果读文件到达文件末尾,返回true。
good()
这是最通用的:如果调用以上任何一个函数返回true 的话,此函数返回 false 。
要想重置以上成员函数所检查的状态标志,你可以使用成员函数clear(),没有参数。
string流
string头文件定义了三个类型来支持内存IO,istringstream向string读取数据,ostringstream从string写数据,stringstream既可从string读取数据也可向string写数据,就像string是一个IO流一样。
istringstream的用法
例子如下:
1 |
|
这相当于把一个句子拆分成单词,联系到前文提到的从文件中读取string的方法,如果读取到的string对象为一个句子,包含很多单词,那么我们就可以运用这种方法把string对象拆分开来。
结果:
1 | Hello |
ostringstream的用法
ostringstream同样是由一个string对象构造而来,ostringstream类向一个string插入字符。
1 |
|
在上例代码中,我们通过put()或者左移操作符可以不断向ostr插入单个字符或者是字符串,通过str()函数返回增长过后的完整字符串数据,但值 得注意的一点是,当构造的时候对象内已经存在字符串数据的时候,那么增长操作的时候不会从结尾开始增加,而是修改原有数据,超出的部分增长。