C++之文件输入输出
C++之文件输入输出
在c++中我们易知的是cout和cin俩个标准输出输入,而在真实的状况中。我们则是需要对文件的内容进行读取和重新写入,这样我们只有cin和cout这俩个标准输入和输出就明显的不够满足条件了。所以有一个fstream类中的ifstream和ofstream则解决了这个对文件操作的问题。
1.文件输入:
我们相比较和之前的标准输出一起来试一下:
标准输出 | 文件输入 |
---|---|
包含头文件iostream类 | 包含头文件fstream类 |
定义了ostream类 | 定义了ofstream类 |
ostream声明了一个cout对象 | ofstream声明了fout(一个或多个自己命名)对象 |
必须指明命名空间std::(cout和endl) | 必须指明命名空间std:: |
结合cout与运算符<<一起显示各种数据 | 需要将之前创建的对象和文件相关联起来(open方法) 也和标准输入一样和运算符<<搭配使用 |
… | 使用完成后需要将对象close() |
如下实例:
#include <iostream> #include <fstream> using namespace std; int main(){ //标准输出(写到显示屏幕上) char ch[] = "hello world!"; cout << ch << endl; //文件输入(写到文件里) ofstream fout; fout.open("data.txt");//将fout对象和文件绑定起来() fout << ch << endl; fout.close(); return 0; }123456789101112131415
1.文件模式:
在上面我们看到了fout.open()是将fout对象和文件绑定起来,那么会有以下情况出现:
- 文件不存在
- 文件存在,但是没有写权限
- 文件存在,权限也正确(不考虑成功)
而我们按照上面的方法则是,如果文件不存在,则创建文件。如果文件存在则是将原来的文件清空,重新写入。(警告:千万不要这样整,万一一不小心将原来文件给删除了,那就一手凉凉了)
这里就得提到了ios_base类定义了一个openmode类型,如下表:
常量 | 含义 |
---|---|
ios_base::in | 打开文件,读取 |
ios_base::out | 打开文件,写入 |
ios_base::ate | 打开文件,移到文件尾 |
ios_base::app | 追加到文件尾 |
ios_base::trunc | 如果文件存在,则截断文件 |
ios_base::binary | 二进制文件 |
而我们在上面的fout.open()其实是有三个参数的,第一个是文件的路径,第二个是打开文件的类型,第三个是权限。如果不写的话,会采用默认参数,就是ios_base::out|ios_base::trunc;也就是会覆盖掉之前文件内容的。
2.文件输出:
还是比较一下标准输入吧:
标准输入 | 文件输出 |
---|---|
包含头文件iostream类 | 包含头文件fstream类 |
定义了istream类 | 定义了ifstream类 |
istream声明了一个cin对象 | ifstream声明了fin(一个或多个自己命名)对象 |
必须指明命名空间std:: | 必须指明命名空间std:: |
结合cin与运算符>>一起显示各种数据 | 需要将之前创建的对象和文件相关联起来(open方法) 也和标准输入一样和运算符>>搭配使用 |
可以使用cin和get()方法读取一个字符,也可以使用getline()来读取一行字符 | 结合ifstream对象使用get()和getline()来读取字符 |
通过cin和eof(),fail()来判断输入是否成功 | 可以结合ifstream对象和eof(),fail()来判断是否读取完文件内容 |
… | 使用完成后需要将对象close() |
测试代码如下:
#include <iostream> #include <fstream> using namespace std; int main(){ //标准输入 char ch; cin >> ch; cout << ch << endl; //文件输入 ifstream fin("data.txt");//可以直接在声明中创建对象 if(!fin.is_open()){ printf("open error!\n"); return -1; } while(fin.good()){ fin >> ch; cout << ch ; } if(fin.eof()){ printf("已经读到文件结尾了!\n"); }else if(fin.fail()){ printf("判断最后一次读取数据的时候是否遇到了类型不配的情况"); }else{//fin.bad() printf("出现意外的问题,如文件受损或硬件故障,最后一次读取数据的时候发生了这样的问题\n"); } fin.close(); return 0; }
1.流状态:
这里我们要提一下上面代码中我们使用的good(),fail(),eof(),bad().等函数是什么呢? 这就牵扯到了流状态检查的概念了
c++文件流类从ios_base类中继承了一个流状态成员,如前面指出的,该成员存储了流状态的信息。good(一切顺利),eof(到达文件结尾),fail(判断结尾是否有误),bad(I/O是否操作失败)。如果一切顺利,则流状态是0(没有消息就是好消息),其他状态都是通过比特位的1来记录的文件流类还继承了ios_base类的报告流状态的方法,可以通过检查流状态来判断是否成功
最后附上c++文件模式和c的区别:
c++模式 | c模式 | 含义 |
---|---|---|
ios_base::in | r | 打开文件,读取 |
ios_base::out | w | 打开文件,写入 |
ios_base::out-ios_base::trunc | w | 打开文件,写入,如果存在文件,则截短文件 |
ios_base::out-ios_base::app | a | 打开文件,追加到文件尾 |
ios_base::in-ios_base::out | r+ | 打开文件读写,在文件允许的位置写入 |
ios_base::in-ios_base::out-ios_base::trunc | w+ | 打开并写入,如果已存在,则截短文件 |
c++mode-ios_base::binary | cmodeb | c++mode和二进制模式打开 |
c++mode-ios_base::ate | cmode | 已指定模式打开,并且移动到文件尾 |