当前位置: 首页 > news >正文

【和春笋一起学C++】文本文件I/O

在windows系统中读取键盘的输入和在屏幕上显示输出统称为:控制台输入/输出。把读取文本文件和把字符输出到文本文件中统称为:文本文件I/O。

目录

1. 输出文本文件

2. 读取文本文件


1. 输出文本文件

把字符输出到文本文件中和输出到控制台很相似,在C++中可以使用cout对象将字符输出到控制台。包含如下步骤:

  1. 包含头文件:#include <iostream>
  2. 指定命名空间:using namespace std;
  3. 使用cout和输出操作符<<将各种类型的数据输出到控制台

C++中将各种类型的数据输出到文本文件的步骤如下:

  1. 包含头文件:#include <fstream>
  2. 指定命名空间:using namespace std;
  3. 创建一个ofstream对象;
  4. 将ofstream对象与输出文件关联起来,方法之一是使用open()方法;
  5. 结合使用ofstream对象和输出操作符<<可以将各种类型的数据输出到文本文件中;
  6. 使用完文件后,应使用close()方法将其关闭;

示例:

#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;

int main()
{
	ofstream outfile;
	outfile.open("testfile.txt");
	outfile << "today is sunday" << endl;
	outfile << "the time is 20:00" << endl;
	outfile.close();

	return 0;
}

头文件iostream提供了预先定义好的在控制台输出的对象——cout,但对于文件输出,需要定义自己的ofstream对象,并将其同输出文件关联起来。所有可用于cout的操作和方法(如:<<,endl和setf())都可用于ofstream对象。

示例中,方法close()不需要使用文件名作为参数,因为outfile对象在使用open()方法时已经同特定的文件关联起来了。如果忘记关闭文件,那么在程序正常终止时将自动关闭它。在程序运行前,如文件不存在,则方法open()将新建一个文件。如文件已存在,默认情况下,open()方法将首先截断该文件,即将其长度截短到零,丢掉其原先的内容,然后将新的输出加入到该文件中。

注:有些情况下,打开文件会失败,如文件已存在且为只读文件。此时,需要程序员检测打开文件的操作是否成功。

2. 读取文本文件

先复习下控制台输入文本的步骤:

  1. 包含头文件iostream
  2. 指定命名空间std
  3. cin和输入操作符>>可以读取任何类型的数据;
  4. 使用cin.get()方法读取一个字符,cin.getline()方法读取一行字符,cin.eof(),cin.fail()方法可以用来判断输入是否成功。

详细可以看我的文章《文本输入与读取(二)》

文件输入与控制台文本输入很相似,步骤如下:

  1. 包含头文件fstream
  2. 定义ifstream类对象
  3. 指定命名空间std
  4. 将ifstream对象与文件关联起来,方法是使用open()方法
  5. 使用完文件,应使用close()方法将其关闭
  6. ifstream对象的方法与cin对象的方法完全相同,使用ifstream对象和输入操作符>>读取数据,ifstream对象的get()方法读取一个字符,getline()方法读取一行字符。

读取文件时,可以先用ifstream类对象的is_open()方法检测文件是否成功打开,否则如果读取了一个不存在的文件,将导致输入失败。如果文件成功打开,方法is_open()将返回ture,反之如果文件没有成功打开,is_open()将返回false。(一些老的编译器如果不支持is_open()方法,可以用good()方法代替

示例:

#include <iostream>
#include <fstream>
#include <cstring>

using namespace std;

int main()
{
	ifstream inFile;
	string filePath = "test.txt";
	inFile.open(filePath);
	if (!inFile.is_open())
	{
		cout << "could not  open the file: " << filePath << endl;
		exit(EXIT_FAILURE);
	}
	double value;
	double sum = 0.0;
	int count = 0;
	inFile >> value;
	while (inFile.good())
	{
		cout << value << "  ";
		++count;
		sum += value;
		inFile >> value;
	}
	cout << value << "  ";
	++count;
	sum += value;
	cout << 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 by unknow reason.\n";
	}

	if (count == 0)
	{
		cout << "no data processed.\n";
	}
	else
	{
		cout << "sum: " << sum << endl;
		cout << "average: " << sum / count << endl;
	}
	inFile.close();
	return 0;
}

程序输出:

程序说明:

  • 程序是读取一个文件中的数据,并求平均值,读取的文本文件中数据如下:

  • 程序首先检测文件是否被成功打开,如果没有成功打卡,则直接退出。函数exit()的原型是在头文件cstdlib中定义的,在该头文件中还定义了一个同操作系统通信的参数值:EXIT_FAILURE。函数exit()表示退出程序。
  • 特别需要注意的是读取循环的设计,程序读取文件时不应超过EOF,如果最后一次读取数据时遇到EOF,方法eof()将返回true。其次可能遇到类型不匹配的情况,如果最后一次读取操作中遇到了类型不匹配的情况,方法fail()将返回true(如果遇到了EOF,该方法也将返回true。fail()方法既可以检测EOF,也可以检测类型不匹配问题)。最后一些预期外的东西也可能导致读取数据失败,例如文件受损、硬盘故障。
  • 方法good()指出最后一次读取输入操作是否成功,这一点至关重要。这意味着应该在执行读取输入操作后,立刻应用这种测试。为此,一种标准的做法是在循环之前(首次执行循环测试前)放置一条输入语句,并在循环的末尾(下次执行循环测试前)放置另一条输入语句。如下:

    inFile >> value;
	while (inFile.good())
	{
        cout << value << "  ";
		++count;
		sum += value;
		inFile >> value;
	}

拓展:表达式inFile >> value的结果为inFile,而在需要一个bool值的情况下,inFile的结果为inFile.good(),即true或false。因此,可以将两条输入语句用一条用作循环测试的输入语句代替。如下:


    while (inFile >> value)
	{
		++count;
		sum += value;
		cout << value << "  ";
	}

这种设计仍然遵循了在测试之前进行读取的规则,因为要计算表达式inFile >> value的值,程序必须首先将一个数字读取到value中。示例代码修改如下:

#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
int main()
{
	ifstream inFile;
	string filePath = "test.txt";
	inFile.open(filePath);
	if (!inFile.is_open())
	{
		cout << "could not  open the file: " << filePath << endl;
		exit(EXIT_FAILURE);
	}
	double value;
	double sum = 0.0;
	int count = 0;
	while (inFile >> value)
	{
		++count;
		sum += value;
		cout << value << "  ";
	}
	cout << 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 by unknow reason.\n";
	}

	if (count == 0)
	{
		cout << "no data processed.\n";
	}
	else
	{
		cout << "sum: " << sum << endl;
		cout << "average: " << sum / count << endl;
	}
	inFile.close();
	return 0;
}

相关文章:

  • Java EE(15)——网络原理——TCP协议解析一
  • 多模态SVG生成新标杆:StarVector从图像文本生成高精度SVG的AI模型
  • 【CXX-Qt】2.4 嵌套对象
  • allWebPlugin中间件自动安装升级
  • mybatis操作数据库报错Cause: Cannot find class: ${com.mysql.cj.jdbc.Driver}
  • 六十天前端强化训练之第二十六天之Vue Router 动态路由参数大师级详解
  • Qt下集成大华网络相机SDK示例开发
  • 大数据学习(76)-Impala计算引擎
  • 【Json-RPC框架】:Json存储结构,operator[ ]返回的就是对应的value对象
  • 根据MAC地址获取设备厂商
  • SOFABoot-06-健康检查
  • 7 合并两个有序列表
  • MediaPipe软件包如何构建和安装
  • Vue中组件和插件有什么区别?
  • Android 根据Url使用Retrofit框架进行文件下载
  • 数字内容体验优化用户参与路径
  • AI比人脑更强,因为被植入思维模型【15】马斯洛需求层次理论
  • 使用Python开发自动驾驶技术:车道线检测模型
  • Java的流程控制
  • 机器学习与数据分析相关数学基础知识总结
  • 现场丨“影像上海”启幕:串联摄影、电影与当代艺术
  • 8大类1000多支,中国红十字会已建成10万人规模救援队伍
  • 云南一男子酒后经常殴打七旬母亲,被警方拘14日罚600元
  • 上海市委常委会扩大会议传达学习习近平总书记考察上海重要讲话和在部分省区市“十五五”时期经济社会发展座谈会上的重要讲话精神
  • 上海飞银川客机触地复飞后备降西安,亲历者:不少乘客都吐了
  • 市场监管总局发布《城镇房屋租赁合同(示范文本)》