![在这里插入图片描述](https://img-blog.csdnimg.cn/20201230214545941.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dkbDIwMTcwMjA0,size_16,color_FFFFFF,t_70)
上图展示了C++中文件IO设计类的基本关系,从中我们可以看出,标准输入与文件输入类继承于同一个基类,标准输出与文件输出类继承于同一个基类。下面针对C++中IO类的一些特性进行介绍。
c++的输入与输出包括以下三个部分:
- 对系统制定的标准设备的输入和输出,称为标准 I/O(设备);
- 以磁盘文件为对象进行输入和输出,称为文件 I/O(文件);
- 对内存中指定的空间进行输入和输出,称为串 I/O(内存);
其中标准I/O如下:
- cin :标准输入流,从键盘输入。
- cout :标准输出流,输出到屏幕。
标准I/O的细节这里不再做过多介绍,我们主要了解文件输入输出。
文件输入输出
文件输入类为iostream,文件输出类为ofstream,和标准I/O的不同在于,文件I/O是从文件输入,输出到文件,在进行文件读写时,一般包括以下几个步骤:
- 打开文件。
- 状态检测。
- 文件读写。
- 文件关闭。
以下是文件读写的示例:
#include <fstream>
#include <iostream>
int main()
{
using namespace std;
char automobile[50];
int year;
double a_price;
double d_price;
ofstream outFile;
outFile.open("carinfo.txt");
if (!outFile.is_open())
return 0;
cout << "Enter the make and model of automobile:";
cin.getline(automobile, 50);
cout << "Enter the model year:";
cin >> year;
cout << "Enter the original asking price:";
cin >> a_price;
d_price = 5 * a_price;
//display information on srceen with cout
cout << fixed;
cout.precision(2);
cout.setf(ios_base::showpoint);
cout << "Make and model:" << automobile << endl;
cout << "Year:" << year << endl;
cout << "Was asking" << a_price << endl;
cout << "Now aksing" << d_price << endl;
//now do exact same things using outFile instead of cout
outFile << fixed;
outFile.precision(2); //用两位小数显示输出
outFile.setf(ios_base::showpoint); //强制显示小数点输出
outFile << "Make and Model:" << automobile << endl;
outFile << "Year:" << year << endl;
outFile << "Was asking:" << a_price << endl;
outFile.close();
//read data from file
ifstream inFile("carinfo.txt");
if (!inFile.is_open())
return 0;
string str;
cout << "read data from file:" << endl;
while (getline(inFile, str))
// while (inFile >> str)
cout << str << endl;
if (inFile.eof())
cout << "End of file reached.\n";
else if (inFile.fail())
cout << "Input terminated by data mismatch.\n";
else
cout << "Input terminated for unknown reason.\n";
return 0;
}
打开文件时,主要有以下模式:
![在这里插入图片描述](https://img-blog.csdnimg.cn/2020123022374010.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dkbDIwMTcwMjA0,size_16,color_FFFFFF,t_70)
针对文件读取得时候,可以使用以下函数进行判断:
- good:读取正常。
- eof:到达文件尾部。
- fail:类型不匹配(例如我们从文件中依次读取赋给int类型,则以空格作为结束,当类型不匹配时,返回)。
- bad: 文件受损或硬件故障。
需要注意的是,我们也可以使用下述方式进行读写正常判断:
while(inFile >> value) //或者getline(inFile, str)
{
...
}
因为这种读取函数只有两个结果,要么true,要么false,所以我们可以直接判断。
缓冲区
每个输出流都有一个缓冲区,用来保存程序读写的数据,如果我们执行文本打印操作,那么文本可能立即打印,也可能不立即打印,此时文本就被保存到了缓冲区;
文本缓冲区之所以存在,是因为设备的读写操作可能都很耗时,允许操作系统将多个输出操作合二为一可以带来性能提升;
如果我们不想使用缓冲,那么就必须进行缓冲刷新,以下方式可以导致刷新:
- 程序正常结束;
- 缓冲区满时;
- 使用操作符 endl;
- 使用 flush;
Note:如果程序崩溃,那么输出缓冲区是不会被刷新的,可能存在这样一种情况:我们通过输出调试信息调试程序,但程序正好崩溃,但实际输出可能已经执行,之所以没有打印只是因为没有缓冲区没有被刷新而已;
参考链接:C++中的流