第17课 文件操作

发布时间:2024年01月06日


前言

文件是指存储在某种长期存储设备(如硬盘、U盘、移动硬盘、光盘等)上的一段数据。这些数据可以以二进制或文本的形式存在,并且被组织成一种特定的结构,以便于程序能够读取和写入。 文件的主要作用是长期保存数据,并在需要时提供对这些数据的访问。
C++把每一个文件看作一个有序的字节流,每个文件都以文件结束标识结束。如果要操作某个文件,程序必须首先打开改文件。当一个文件被打开后,该文件就和一个流关联起来,这里的流实际上是一个字节序列。

C++将文件分为文本(字符)文件和二进制文件。二进制文件一般含有特殊的格式或计算机代码,如图像文件和可执行文件等。文本文件则是可以用任何文字处理程序打开浏览和编辑的简单字符序列文件。

文件可以用来存放程序的输入输出结果。我们比赛中所有程序的输入输出都是由文件完成的,而不是直接用键盘和显示器进行输入输出。

下面我们学习如何编写 C ++代码来实现对文本文件(即字符文件)的输入和输出。

一、C++中的文件操作

文件操作基本步骤如下。

  1. 打开文件,将文件指针指向文件。
  2. 对文件进行读写操作
  3. 在使用完文件后,关闭文件

C++中,文件时文件输入流(ifstream)和文件输出流(ofstream)的默认输入输出设备。C++可以在创建文件流变量时,设定输入输出到哪个文件。

C++源程序中的文件操作关键语句见表17-1所示。

表17-1 C++源程序中文件操作的常见用法

操作说明
#include引入文件流类
ifstream fin(“filename”);使用fin作为文件输入流对象,同时打开指定的文件
ofstream fout(“filename”);使用fout作为文件输出流对象,同时打开指定的文件
fin != NULL判断文件是否打开(是否存在)
!fin.eof()文件指针还没有到文件末尾
fin>>变量名;从输入文件中读取数据
fout<<变量名;将数据写入输出文件
fin.close();fout.close();关闭输入/输出文件

二、使用步骤

1. 打开文件

打开文件的一般形式如下。

ifstream fin("input.txt");
//fstream fin("input.txt", ios::in);//等价于上一行
if (!fin) {
    cout << "打开文件出错" << endl;
    return ;
}

2. 逐行读取数据

逐行读入数据需要用到getline()函数,而且逐行读取的字符串,是没有换行符的!所以要将读取的一行信息写入一个新的文件中,需要添加换行符。
代码如下(示例)

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

int main() {
	string aline;
	ifstream fin("Hold_fast_to_dreams.txt");
	ofstream fout("Hold_fast_to_dreams2.txt");
	while(!fin.eof()) {
		getline(fin, aline);
		fout << aline << endl;	// add line break into new file
	}

	fin.close();
	fout.close();
	cout << "Done!" << endl;
    return 0;
}

设Hold_fast_to_dreams.txt的内容如下。

Hold fast to dreams 紧紧抓住梦想,
For if dreams die 梦想若是消亡
Life is a broken-winged bird 生命就象鸟儿折了翅膀
That can never fly. 再也不能飞翔
Hold fast to dreams 紧紧抓住梦想,
For when dreams go 梦想若是消丧
Life is a barren field 生命就像贫瘠的荒野,
Frozen only with snow 雪覆冰封,万物不再生。

运行程序,则程序将Hold_fast_to_dreams.txt的内容原样复制到文件Hold_fast_to_dreams2.txt中。

上面的程序也可以写成下面的形式,效果是一样的。

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

int main() {
	string aline;
	ifstream fin("Hold_fast_to_dreams.txt");
	ofstream fout("Hold_fast_to_dreams3.txt");
	while(getline(fin, aline)) {
		fout << aline << endl;
	}
	fin.close();
	fout.close();
	cout << "Done!" << endl;
    return 0;
}

3. 逐个字符地读取数据(忽略空格与回车)

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

int main() {
	char ch;
	ifstream fin("Hold_fast_to_dreams.txt");
	ofstream fout("Hold_fast_to_dreams4.txt");
	while(!fin.eof()) {
		fin >> ch;
		fout << ch;
	}
	fin.close();
	fout.close();
	cout << "Done!" << endl;
	return 0;
}

运行程序,生成的Hold_fast_to_dreams4.tx文件内容如下。

Holdfasttodreams紧紧抓住梦想,Forifdreamsdie梦想若是消亡Lifeisabroken-wingedbird生命就象鸟儿折了翅膀Thatcanneverfly.再也不能飞翔Holdfasttodreams紧紧抓住梦想,Forwhendreamsgo梦想若是消丧Lifeisabarrenfield生命就像贫瘠的荒野,Frozenonlywithsnow雪覆冰封,万物不再生。?

可见,Hold_fast_to_dreams.tx文件中德空格与回车并没有读取。此外,在生成的Hold_fast_to_dreams4.tx文件内容的末尾多了一个问号?。

4. 逐个字符地读取数据(包括空格与回车)

逐个字符读入字符文件内容时,如果需要包括空格与回车,可以对文件输入流进行设置如下。

fin >> noskipws;

示例代码如下。

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

int main() {
	char ch;
	ifstream fin("Hold_fast_to_dreams.txt");
	ofstream fout("Hold_fast_to_dreams5.txt");
	fin >> noskipws;
	while(!fin.eof()) {
		fin >> ch;
		fout << ch;
	}
	fin.close();
	fout.close();
	cout << "Done!" << endl;
	return 0;
}

运行程序,生成的Hold_fast_to_dreams5.tx文件内容如下。

Hold fast to dreams 紧紧抓住梦想,
For if dreams die 梦想若是消亡
Life is a broken-winged bird 生命就象鸟儿折了翅膀
That can never fly. 再也不能飞翔
Hold fast to dreams 紧紧抓住梦想,
For when dreams go 梦想若是消丧
Life is a barren field 生命就像贫瘠的荒野,
Frozen only with snow 雪覆冰封,万物不再生。?

5. 将数据写入文件

一般步骤是:先打开文件流,往流里面插入数据信息,然后关闭文件流。
下面的语句是以覆盖模式打开一个写入流。

ofstream fout("letter2.txt");

下面的语句是以追加模式打开一个写入流。

ofstream fout;
fout.open("letter2.txt", ios::app); //末尾追加模式

完整的示例代码如下。

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

int main() {
	string aline;
	ifstream fin("Hold_fast_to_dreams.txt");
	//ofstream fout("Hold_fast_to_dreams3.txt");
	ofstream fout;
	fout.open("letter2.txt", ios::app); //末尾追加模式
	fout << endl;
	while(getline(fin, aline)) {
		fout << aline << endl;
	}
	fin.close();
	fout.close();
	cout << "Done!" << endl;
    return 0;
}

课后练习

3. 文件的读取和写入

letter.txt文件中有一行英文字符,编程读取这一行字符,然后将这一行字符中的英文字母写入另一文件 alphabet.txt中,忽略其它字符,但保留空格。

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

int main() {
	char ch;
	ifstream fin("letter.txt");
	ofstream fout("alphabet.txt");
	while(fin >> ch) {
		if(ch>='a' && ch<='z' || ch>='A' && ch<='Z' || ch==' ')
			fout << ch;
	}
	fin.close();
	fout.close();
	cout << "Done!" << endl;
	return 0;
}

循环中,while(fin >> ch) 表示文件没有结束则继续输入字符给ch。
上面的代码页可以写成如下形式。

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

int main() {
	char ch;
	ifstream fin("letter.txt");
	ofstream fout("alphabet2.txt");
	while(!fin.eof()) {
		fin >> ch;
		if(ch>='a' && ch<='z' || ch>='A' && ch<='Z' || ch==' ')
			fout << ch;
	}
	fin.close();
	fout.close();
	cout << "Done!" << endl;
	return 0;
}

设letter.txt文件的内容如下。

A world without the Amazon? Safeguarding the Earth’s largest rainforest ...

运行程序,则生成的alphabet.txt文件的内容如下。

AworldwithouttheAmazonSafeguardingtheEarthslargestrainforest

显然,在使用fin >> ch读取letter.txt文件中的字符内容时,已默认忽略掉空格与回车。
如果读取时要包括空格与回车,可以对输入流进行如下设置。

fin >> noskipws;

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

int main() {
	char ch;
	ifstream fin("letter.txt");
	ofstream fout("alphabet3.txt");
	fin >> noskipws;
	while(fin >> ch) {
		if(ch>='a' && ch<='z' || ch>='A' && ch<='Z' || ch==' ')
			fout << ch;
	}
	fin.close();
	fout.close();
	cout << "Done!" << endl;
	return 0;
}

此时再运行程序,则生成的alphabet3.txt文件的内容如下。

A world without the Amazon Safeguarding the Earths largest rainforest 

4. 文件的复制

编写程序,将文件letter2.txt的内容输出到屏幕上并复制到letter3.txt中。

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

int main() {
	string aline;
	ifstream fin("letter2.txt");
	ofstream fout("letter3.txt");
	//ofstream fout;
	//fout.open("letter3.txt", ios::app); //末尾追加模式
	while(getline(fin, aline)) {
		cout << aline << endl;
		fout << aline << endl;
	}
	fin.close();
	fout.close();
	cout << "Done!" << endl;
    return 0;
}

5. 文件中的整数统计

已知number.txt中存入了一些整数,整数之间以空格分隔,请编写程序统计文件中正整数、零和负整数的个数,并存入statistics.txt文件中。

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

int main() {
	int n, plus=0, zero=0, negative=0;
	ifstream fin("number.txt");
	ofstream fout("statistics.txt");
	//fin >> noskipws;
	while(!fin.eof()) {
		fin >> n;
		if(n>0) plus++;
		else if(n<0) negative++;
		else zero++;
	}
	fout << plus << ' ' << zero << ' ' << negative;
	fin.close();
	fout.close();
	cout << "Done!" << endl;
	return 0;
}

设number.txt文件的内容如下。

54 23 0 45 0 -2 -97 24 78 -3 -67 95 -25 40 -39 0

运行程序,生成的statistics.txt文件内容如下。

7 3 6

总结

本课主要介绍了如下内容。

  1. 文件的概念
  2. 字符文件的操作过程
  3. 字符文件的读取和写入
文章来源:https://blog.csdn.net/red2brick/article/details/135407583
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。