对于文件操作的一个实例【摘自c++ primer plus】

写在前面:在学习文件操作时,因为跳过了一页所以没有看到cin.get() 会改变流状态所以犯了这个错误。这是我看书时两段程序的拼接,所以文件打开关闭了两次,在这里写下我对这段代码的理解以供日后参考。 

#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
const int LIM = 20;
struct planet {
	char name[LIM];
	double population;
	double g;
};
const char* file = "planets.dat";
inline void eatline() { while (std::cin.get() != '\n')continue; }

int main() {
	using namespace std;
	planet pl;
	cout << fixed;

	//add elements
	fstream ftemp(file,
		ios_base::out|ios_base::binary);
	if (!ftemp.is_open()) {
		cerr << "Can't open"<<file<<" file for output.\n";
		exit(EXIT_FAILURE);
	}
	cout << "Enter planet name (enter a blank line to quit): ";
	cin.get(pl.name, 20);
	cout << cin.rdstate()<<endl;
	while (pl.name[0] != '\0') {
		eatline();
		cout << "Enter planetary population: ";
		cin >> pl.population;
		cout << "Enter planet's acceleration of gravity: ";
		cin >> pl.g;
		eatline();
		ftemp.write((char*)&pl, sizeof pl);
		cout << "Enter planet name (enter a blank line to quit): ";
		cin.get(pl.name, 20);
		cout << cin.rdstate()<<endl;
	}
	cin.clear();
	ftemp.close();
	//if (cin.good()) cout << "good\n";
	//if (cin.eof()) cout << "eof\n";
	//if (cin.bad()) cout << "bad\n";
	//if (cin.fail()) cout << "fail\n";
	//show contents
	fstream finout;
	finout.open(file,
		ios_base::in | ios_base::out | ios_base::binary);
	int ct = 0;
	if (finout.is_open()) {
		finout.seekg(0);
		cout << "Here are the current contents of the "
			<< file << " file:\n";
		while (finout.read((char*)&pl, sizeof pl)) {
			cout << ct++ << ": " << setw(LIM) << pl.name << ": "
				<< setprecision(0) << setw(12) << pl.population
				<< setprecision(2) << setw(6) << pl.g << endl;
		}
		if (finout.eof()) finout.clear();
		else {
			cerr << "Error in reading " << file << ".\n";
			exit(EXIT_FAILURE);
		}
	}
	else {
		cerr << file << " could not be opened -- bye.\n";
		exit(EXIT_FAILURE);
	}
	//change a record
	cout << "Enter the record number you wish to change: ";
	long rec = 0;
	//eatline();
	//getchar();
	cin >> rec;
	eatline();
	
	if (rec < 0 || rec >= ct) {
		cerr << "Invalid record number -- bye\n";
		exit(EXIT_FAILURE);
	}
	streampos place = rec * sizeof pl;
	finout.seekg(place);
	if (finout.fail()) {
		cerr << "Error on attempted seek\n";
		exit(EXIT_FAILURE);
	}

	finout.read((char*)&pl, sizeof pl);
	cout << "Your selection:\n";
	cout<<rec<<": "<<setw(LIM)<<pl.name<<": "
		<< setprecision(0) << setw(12) << pl.population
		<< setprecision(2) << setw(6) << pl.g << endl;
	if (finout.eof()) finout.clear();

	cout << "Enter planet name: ";
	cin.get(pl.name, LIM);
	eatline();
	cout << "Enter planetary population: ";
	cin >> pl.population;
	cout << "Enter planet's acceleration of gravity: ";
	cin >> pl.g;
	finout.seekp(place);
	finout.write((char*)&pl, sizeof pl);
	if (finout.fail()) {
		cerr << "Error on attempted write\n";
		exit(EXIT_FAILURE);
	}
	//show revised file
	ct = 0;
	
	finout.seekg(0);
	cout << "Here are the new contents of the "
		<< file << " file:\n";
	while (finout.read((char*)&pl, sizeof pl)) {
		cout << ct++ << ": " << setw(LIM) << pl.name << ": "
			<< setprecision(0) << setw(12) << pl.population
			<< setprecision(2) << setw(6) << pl.g << endl;
	}
	finout.close();
	cout << "Done.\n";
	return 0;
}

 运行过程:

1.创建二进制文件 planets.dat 并打开,进行写入操作(如果已有该文件将清楚文件内容重新写入)。这里我添加了一句输出 cin 的流状态,可在每次输入 name 检查流状态,因为一开始我没有注意流状态所以文件只能进行到第一次写入而不能继续接下来的 cin 操作。

2.执行完第一段后就会发现,cin 的流状态变为了 failbit ,导致不能继续读入数据。流状态变为 failbit 的原因是因为 cin.get() 函数读取了一个空行(这里程序以接收空行为结束标志)。因此需要重置流状态,调用一次 cin.clear() 函数即可。

3.再次打开文件,以读写二进制文件的形式。如果打开文件则将文件的读指针移到文件开头,从开头读到文件结尾即读出文件所有信息,此时流状态被设为 eofbit ,再对流状态进行重置,同上使用clear() 函数。

4.进行更改信息操作。读入信息标号从而确定选定的信息,将该信息输出后进行写入覆盖原有的数据,完成更新。

5.最后将文件信息完整输出一遍。

运行示例:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值