文件输入输出(文本文件、二进制文件)(ifstream、ofstream)

在这里插入图片描述

一.写入文件流程

  1. 创建一个ofstream对象来管理输出流。
  2. 将该对象与特定文件关联起来。
  3. 以使用cout方式使用该对象,唯一区别是输出进文件,不是屏幕。
  4. 关闭文件流.
ofstream fout;
fout.open(filename);
//上面两步可以合并为:
ofstream fout(filename);//直接调用ofstream 类的构造函数
fout<<"data";//写入文件
fout.close();

二.读取文件流程

  1. 创建一个ifstream对象管理输入流。
  2. 将该对象与特定的文件关联起来。
  3. 以使用cin的方式使用该对象。
  4. 关闭文件流。
ifstream fin;
fin.open(filename);
//上面两步可以合并为:
ifstream fin(filename);//直接调用ifstream 类的构造函数
//以使用cin的方式使用该对象。
char ch;
fin>>ch;//从filename中读取一个字符
char buf[80];
fin>>buf;//从filename读取80个字符
fin.getline(buf,80);//从文件中读取一行
string line;
getline(fin,line);//从文件中读取一行

fin.close();

三.检查文件流是否打开成功

fin.open(filename);//创建文件流
//方法一
if(fin.fail()){
	cout<<"文件打开失败!"<<endl;
}
//方法二
if(!fin){
	cout<<"文件打开失败!"<<endl;
}
//方法三
if(!fin.is_open()){
	cout<<"文件打开失败!"<<endl;
}

其中,方法三更好用,因为它能够检测出其他方式不能检测出的微妙问题。

四.文件写入、读取例子

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

int main() {
	string filename;
	cout << "input file name:" << endl;
	cin >> filename;
	//创建文件的输出流
	ofstream fout(filename.c_str());
	fout << "For your eyes only!\n";//写向文件
	cout << "Enter secret number:";//写向屏幕
	float secret;
	cin >> secret;
	fout << "Your secret number is " << secret << endl;
	fout.close();
	//创建文件的输入流
	ifstream fin(filename);
	if (!fin.is_open()) {
		cout << "文件打开失败!" << endl;
	}
	cout << "Here are the contents of " << filename << ":" << endl;
	char ch;
	while (fin.get(ch))
		cout << ch;
	cout << "Done\n";
	fin.close();
}

在这里插入图片描述

五.文件模式

文件模式是描述文件将被如何使用:读、写、追加等。
在这里插入图片描述
trunc:单词原型为:truncate,译为截断。
因此,ios_base::trunc:打开已有的文件,以接受成熟输出时将被截断;也就是删除以前的内容。
ios_base::out:本身也会导致文件被截断,相当于先删除以前文件内容,再写入文件。
app:单词原型为append,译为追加。
使用方法:

	ifstream fin(filename, C++mode);//调用构造函数,同时申明模式
	//或
	ofstream fout;
	fout.open(filename, C++mode);//在open函数中申明模式

在这里插入图片描述
ios_base::ate和ios_base::app都将文件指针指向打开的文件尾。二者的区别在于,前者将指针放在文件尾;后者只允许将数据添加到文件尾。

六.追加文件案例

#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>//for exit()
using namespace std;

const char* file = "guest.txt";
int main() {
	char ch;
	ifstream fin;
	fin.open(file);
	if (fin.is_open()) {
		cout << "Here are the current content of the " << file << " file:\n";
		while (fin.get(ch))
			cout << ch;
		fin.close();
	}
	ofstream fout(file, ios_base::out | ios_base::app);
	if (!fout.is_open()) {
		cerr << "Can't open " << file << " file for output.\n";
		exit(EXIT_FAILURE);
	}
	cout << "Enter guest names (enter a blank line to quit):\n";
	string name;
	cin >> name;
	fout << name << endl;
	//show revise file
	fin.clear();//not necessary for some compiler
	fin.open(file, ios_base::in);
	if (fin.is_open()) {
		cout << "Here are the new contents of the " << file << " file:\n";
		while (fin.get(ch))
			cout << ch;
		fin.close();
	}

在这里插入图片描述

七.二进制文件

将数据存储在文件中,可以将其存储为文本格式或二进制格式。
文本格式:指的是将所有内容(甚至是数组)都存储为文本。例如,以文本格式存储值**-2.324216e+07**,将存储该数字包含的13个字符。
二进制格式:指的是存储值的计算机内部表示。也就是说,计算机不是存储字符,而是存储这个值的64位double表示。
对于字符来说,二进制表示和文本表示都是一样的,即字符的ASCII码的二进制表示。但是对于数字来说,二进制表示与文本表示有很大的差别。
例如:
0.375的二进制表示
0(符号位)0111110(指数位)110000000000000000000000(二进制分数位)
0.375的文本表示
00110000(字符0编码)00101110(字符 . 编码)00110011(字符3编码)00110111(字符7编码)00110111(字符5编码)

优缺点:
文本格式:便于读取,可以使用编译器或字处理器来读取和编辑文本文件,可以很方便地将文本文件从一个计算机系统传输到另一个计算机系统。
二进制文件:对数字来说比较精确,因为他存储的是值的内部表示,不会出现转换误差和舍入误差。同时,保存数据更快,因为不需要转换,占用空间较小。然而,如果另一个系统使用另一种内部表示,则可能无法将数据传输给该系统。

使用:

const int LIM = 20;
struct planet
{
	char name[LIM];
	double population;
	double g;
};
planet p1;
ofstream fout("planet.dat", ios_base::out | ios_base::binary);//ios_base::binary二进制
fout.write((char*)&p1, sizeof p1);
//程序前往p1结构的地址,并将开始的36个字节(sizeof p1表达式的值)复制到与fout关联的文件中

//信息恢复
ifstream fin("planet.dat", ios_base::out | ios_base::binary);//ios_base::binary二进制
fin.read((char*)&p1, sizeof p1);//read()将从文件中复制sizeof p1个字节到p1结构中。

write():这种方法将内存中指定数目的字节复制到文件中,必须将地址强制转换为char的指针。

使用案例:

#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>//for exit()
using namespace std;

inline void eatline() { while (cin.get() != '\n') continue; }
const char* file = "planets.dat";
struct planet
{
	char name[20];
	double population;
	double g;
};
int main() {
	planet p1;
	cout << fixed << right;
	//show initial contents
	ifstream fin(file, ios_base::out | ios_base::binary);
	if (fin.is_open()) {
		cout << "Here are the current contents of the " << file << " file:\n";
		while (fin.read((char*)&p1, sizeof p1)) {//写入p1中
			cout << setw(20) << p1.name << ":" << setprecision(0) << setw(12) << p1.population << setprecision(2) << setw(6) << p1.g << endl;
		}
		fin.close();
	}
	//add data
	ofstream fout(file, ios_base::out | ios_base::binary|ios_base::app);
	if (!fout.is_open()) {
		cerr << "Can't open" << file << "file for output:\n";
		exit(EXIT_FAILURE);
	}
	cin.get(p1.name, 20);
	while (p1.name[0] != '\0') {
		eatline();
		cout << "Enter planetary population:";
		cin >> p1.population;
		cout << "Enter planet's acceleration of gravity:";
		cin >> p1.g;
		eatline();
		fout.write((char*)&p1, sizeof p1);
		cout << "输入回车结束,再次输入name:" << endl;
		cin.get(p1.name, 20);
	}
	fout.close();
	//show revised file
	fin.clear();//not required for some implementations,but won't hurt
	fin.open(file, ios_base::out | ios_base::binary);
	if (fin.is_open()) {
		cout << "Here are the current contents of the " << file << " file:\n";
		while (fin.read((char*)&p1, sizeof p1)) {//写入p1中
			cout << setw(20) << p1.name << ":" << setprecision(0) << setw(12) << p1.population << setprecision(2) << setw(6) << p1.g << endl;
		}
		fin.close();
	}
	cout << "Done" << endl;
}

在这里插入图片描述

八.EOF()函数

EOF:原型end of file,用于判断作为文件结束标志的文件,必须是文本文件。

while (!infile.eof())

九.以前笔记

功能:将source.txt文件中内容,写进target.txt文件中。
source.txt文件
在这里插入图片描述
target.txt文件
在这里插入图片描述

读文件
两种方法,如下:

#include <iostream>
#include <fstream>//引入文件读写的头文件
using namespace std;

//文件路径
string source = "C:\\Users\\19a405\\Desktop\\source.txt";
string target = "C:\\Users\\19a405\\Desktop\\target.txt";
int main() {
	//方法一:调用ifstream类构造函数
	ifstream ism1(source,ios::in);//只读方式打开文件
	//方法二:调用ifstream类内部函数open()
	ifstream ism2;
	ism2.open(source, ios::in);
	//判断文件是否打开成功
	if (!ism1) {//这里在ifstream类中重载了!号
		cout << "文件打开失败!" << endl;
	}
	//读文件
	char ch;
	//get()每次读取一个字符,就是cin.get()作用
	while (ism1.get(ch))
	{
		cout << ch;
	}
	//关闭文件
	ism1.close();
}

结果:
在这里插入图片描述

写文件

#include <iostream>
#include <fstream>//引入文件读写的头文件
using namespace std;

//文件路径
string source = "C:\\Users\\19a405\\Desktop\\source.txt";
string target = "C:\\Users\\19a405\\Desktop\\target.txt";
int main() {
	//读文件
	//方法一:调用ifstream类构造函数
	ifstream ism1(source,ios::in);//只读方式打开文件
	//方法二:调用ifstream类内部函数open()
	ifstream ism2;
	ism2.open(source, ios::in);

	//写文件
	//方法一
	ofstream osm1(target, ios::out);
	//方法二
	ofstream osm2;
	osm2.open(target, ios::out);

	//判断文件是否打开成功
	if (!ism1) {//这里在ifstream类中重载了!号
		cout << "文件打开失败!" << endl;
	}
	//读文件
	char ch;
	while (ism1.get(ch))//get()每次读取一个字符,就是cin.get()作用
	{
		cout << ch;
		//给target写内容
		osm2.put(ch);
	}
	//关闭文件
	ism1.close();
	osm2.close();
}

结果:
在这里插入图片描述

问题
我们再次运行上述写文件代码。
结果:依然没变。
在这里插入图片描述
但是,我们想在文件后面进行追加后续文字,出现两个“我怀念的 等”。

文件追加
修改:增加ios::app.

//写文件
//方法一
ofstream osm1(target, ios::out|ios::app);
//方法二
ofstream osm2;
osm2.open(target, ios::out|ios::app);

继续运行:
结果:
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值