文件与基本读写
参考《NOI大纲》
- 文件的基本概念、文本文件的基本操作
- 文本文件类型与二进制文件类型
- 文件重定向、文件读写等操作
文件输入输出
文件的概念
在 C++ 中,每一个文件都是一个有序的字节流,每个文件都是以文件结束标志(EOF) 结束,如果要操作某个文件,步骤如下:
- 以指定的模式(读或写)打开文件
- 对文件进行读、写操作
- 操作完成后,关闭该文件
在 C++ 中有 fstream
和 freopen
两种方式用于文件输入输出。
fropen
函数
freopen
是 C 语言中的函数,用于重新定向标准输入输出流到指定的文件。它可以用于改变程序默认的输入输出流,使程序从文件中读取输入或将输出写入文件。使用 freopen
需要引入 <cstdio>
头文件。
看下面一个示例:
#include <cstdio>#include <iostream>using namespace std;
int main() { // 读入指定文件内容 freopen("problem.in", "r", stdin); // 输出到文件 freopen(("problem.out"), "w", stdout);
int a, b, c; cin >> a >> b >> c; cout << "三数之和为 " << a + b + c << endl;
// 关闭标准输入/输出流 fclose(stdin); fclose(stdout);
return 0;}
可以看到,一旦我们使用 freopen
函数将标准的 stdin / stdout
重定向后,当我们使用 cin / out / scanf / printf
等函数进行输入输出时,都将被定向到指定的文件。
fstream
函数
fstream
是 C++ 中的文件输入输出流类。它提供了打开、读取和写入文件的功能。你可以使用 ifstream
类进行文件读取操作,使用 ofstream
类进行文件写入操作,或者使用 fstream
类同时进行读写操作。
需要注意的是,当我们使用
fstream
函数在读写文件时,就不能使用 C 风格的输入输出scanf
和prinft
了。
#include <fstream>using namespace std;
int main() { // 读入 ifstream fin("problem.in"); // 输出 ofstream fout ("problem.out");
int a, b, c; cin >> a >> b >> c; cout << "三数之和为 " << a + b + c << endl;
// 关闭标准输入/输出流 fin.close(); fout.close();
return 0;}
freopen
与 fstream
比较
fstream
是 C++ 的标准库,而 freopen
是 C 语言的函数,在 C++ 中,两者都可以使用。
相对来说,fstream
提供了更多的功能和灵活性,适用于 C++ 中对文件进行读写操作的场景。而 freopen
则是用于重定向标准输入输出流的 C 语言函数,在 C++ 中也可以使用。具体使用哪种方式取决于你的需求和编程环境。
【需重新梳理一遍】
C++ 文件读写与 Competitive Programming 相关内容
在 C++ 中进行文件读写是一项重要技能,尤其是在需要本地测试或者题目要求文件输入输出时。本文将详细讲解以下几个部分:
- 文件的基本概念与文本文件的基本操作
- 文本文件与二进制文件的区别及操作
- 文件重定向的概念与实现
- 文件读写技巧在竞赛编程中的应用
1. 文件的基本概念与文本文件的基本操作
什么是文件?
- 文件是存储在磁盘或其他存储设备上的数据集合。
- C++ 文件操作通过
fstream
头文件中的类来实现,包括:ifstream
(输入文件流):用于读文件。ofstream
(输出文件流):用于写文件。fstream
(文件流):同时支持读写文件。
文本文件的基本操作
文本文件是以 ASCII 或 UTF-8 格式存储的文件,主要存储可见字符。
1. 读文件(ifstream
)
#include <iostream>#include <fstream>using namespace std;
int main() { ifstream inputFile("input.txt"); // 打开文件以读取数据 if (!inputFile.is_open()) { cerr << "无法打开文件!" << endl; return 1; }
int x, y; inputFile >> x >> y; // 从文件中读取两个整数 cout << "读取的数是: " << x << " 和 " << y << endl;
inputFile.close(); // 关闭文件 return 0;}
2. 写文件(ofstream
)
#include <iostream>#include <fstream>using namespace std;
int main() { ofstream outputFile("output.txt"); // 打开文件以写入数据 if (!outputFile.is_open()) { cerr << "无法打开文件!" << endl; return 1; }
int result = 42; outputFile << "结果是: " << result << endl; // 将数据写入文件
outputFile.close(); // 关闭文件 return 0;}
3. 读写文件(fstream
)
fstream
同时支持读写操作,常用于需要对文件进行多次访问的场景:
#include <iostream>#include <fstream>using namespace std;
int main() { fstream file("data.txt", ios::in | ios::out | ios::trunc); // 读写模式打开,清空原内容 if (!file.is_open()) { cerr << "文件无法打开!" << endl; return 1; }
// 写入数据 file << "Hello World" << endl;
// 将文件指针移到文件开头 file.seekg(0, ios::beg);
// 读取数据 string data; getline(file, data); cout << "读取内容: " << data << endl;
file.close(); return 0;}
2. 文本文件与二进制文件的区别及操作
区别:
-
文本文件:
- 数据存储为字符格式,可用文本编辑器打开查看。
- 数据经过编码和解码,通常较大。
-
二进制文件:
- 数据以二进制格式存储,存储的是原始数据。
- 更紧凑,读取更快,但不能直接用文本编辑器查看。
文本文件与二进制文件的读写
文本文件读写(默认模式)
文本文件是 C++ 文件流的默认模式。
ofstream outputFile("text.txt"); // 默认文本写入outputFile << "12345" << endl; // 输出字符串,按字符存储outputFile.close();
二进制文件读写
二进制文件使用 ios::binary
标志,数据直接存储为原始格式。
示例:写入和读取二进制文件
#include <iostream>#include <fstream>using namespace std;
int main() { // 写二进制文件 ofstream outFile("binary.dat", ios::binary); // 以二进制模式打开 int a = 12345; outFile.write((char*)&a, sizeof(a)); // 写入原始数据 outFile.close();
// 读二进制文件 ifstream inFile("binary.dat", ios::binary); int b; inFile.read((char*)&b, sizeof(b)); // 读取原始数据 cout << "读取的数是: " << b << endl;
inFile.close(); return 0;}
3. 文件重定向的概念与实现
文件重定向的概念
文件重定向是一种将程序的标准输入/输出流重定向到文件的技术。
- 输入重定向:让
cin
从文件中读取数据,而不是键盘。 - 输出重定向:让
cout
将结果写入文件,而不是输出到屏幕。
freopen
实现文件重定向
重定向输入与输出
#include <iostream>using namespace std;
int main() { freopen("input.txt", "r", stdin); // 将标准输入重定向到 input.txt freopen("output.txt", "w", stdout); // 将标准输出重定向到 output.txt
int a, b; cin >> a >> b; // 从 input.txt 读取数据 cout << a + b << endl; // 将结果输出到 output.txt
return 0;}
重定向的优点:
-
代码无需修改:
使用cin
和cout
的代码无需更改,只需添加freopen
。 -
适合竞赛场景:
在本地测试时,将测试数据放入文件,可以快速调试。
4. 文件读写在竞赛编程中的应用
在 Competitive Programming 中,文件操作主要用于:
-
测试本地样例数据:
将输入放入input.txt
,程序从文件读取,输出到output.txt
,方便本地调试。 -
处理大规模数据:
对于较大的输入输出数据,文件 I/O 可以提高运行效率。 -
平台要求:
某些竞赛平台可能要求程序使用文件输入输出。
推荐模板:文件重定向
#include <iostream>using namespace std;
int main() { freopen("input.txt", "r", stdin); // 重定向标准输入到 input.txt freopen("output.txt", "w", stdout); // 重定向标准输出到 output.txt
// 竞赛代码示例 int n, sum = 0; cin >> n; // 从 input.txt 读取数据 for (int i = 0; i < n; i++) { int x; cin >> x; sum += x; } cout << "总和: " << sum << endl; // 输出到 output.txt
return 0;}
5. 常见错误与注意事项
-
文件路径问题:
- 确保文件与程序在同一目录。
- 使用完整路径时,路径要正确。
-
文件未关闭:
- 使用
close()
关闭文件,释放资源。
- 使用
-
忘记重定向标准输入输出:
- 文件重定向时,要使用正确的
freopen
语句。
- 文件重定向时,要使用正确的
-
文本模式与二进制模式混淆:
- 文本文件和二进制文件要分清操作模式。
-
平台限制:
- 某些在线评测系统可能不支持
freopen
。
- 某些在线评测系统可能不支持
总结
在 C++ 的文件读写中:
- 使用
ifstream
和ofstream
实现文本文件的读取和写入。 - 使用
ios::binary
打开二进制文件,直接读写原始数据。 - 使用
freopen
重定向标准输入输出,适合竞赛本地测试。
掌握这些技巧后,可以在竞赛编程中高效处理文件读写任务,提高程序调试效率!