C++文件读写通过fstream类实现,需包含<fstream>头文件,使用ofstream写入、ifstream读取、fstream读写;通过open()或构造函数打开文件,指定模式如ios::in、ios::out、ios::binary等;操作前检查is_open(),用<<和>>进行文本读写,read()和write()进行二进制读写,最后调用close()关闭文件;常见模式包括文本模式(自动转换换行符,适合人类可读数据)和二进制模式(原样读写字节,适合高效处理原始数据);错误处理可通过is_open()、fail()、bad()、eof()等状态标志判断,也可启用exceptions()抛出异常;二进制读写需注意字节序、数据对齐及指针成员的序列化问题。

C++中读取和写入文件,核心是通过标准库中的
fstream
ifstream
ofstream
cin
cout
要进行C++文件读写,我们通常会遵循以下步骤:
<fstream>
ofstream
ifstream
fstream
open()
is_open()
<<
write()
>>
getline()
read()
close()
示例:文本文件写入
#include <fstream>
#include <iostream>
#include <string>
// 假设我们想把一些文本写入一个叫做 "example.txt" 的文件
void writeTextToFile() {
std::ofstream outFile("example.txt"); // 尝试打开文件用于写入,如果文件不存在则创建
if (!outFile.is_open()) { // 检查文件是否成功打开
std::cerr << "错误:无法打开文件 example.txt 进行写入。" << std::endl;
return;
}
outFile << "你好,C++文件写入!\n"; // 写入一行文本
outFile << "这是第二行内容。\n";
outFile << "数字也可以写入:" << 12345 << std::endl; // 写入数字和换行符
outFile.close(); // 关闭文件
std::cout << "数据已成功写入 example.txt。" << std::endl;
}示例:文本文件读取
立即学习“C++免费学习笔记(深入)”;
#include <fstream>
#include <iostream>
#include <string>
// 现在我们来读取刚才写入的文件
void readTextFromFile() {
std::ifstream inFile("example.txt"); // 尝试打开文件用于读取
if (!inFile.is_open()) { // 检查文件是否成功打开
std::cerr << "错误:无法打开文件 example.txt 进行读取。" << std::endl;
return;
}
std::string line;
// 逐行读取文件直到文件末尾
while (std::getline(inFile, line)) {
std::cout << "读取到一行: " << line << std::endl;
}
inFile.close(); // 关闭文件
std::cout << "example.txt 文件读取完毕。" << std::endl;
}
// 可以在 main 函数中调用这两个函数测试
// int main() {
// writeTextToFile();
// readTextFromFile();
// return 0;
// }在C++中进行文件操作,理解不同的文件打开模式和有效的错误处理机制是构建健壮应用程序的关键。在我看来,这不仅仅是语法上的知识点,更是编程实践中避免“黑盒”错误的重要一环。
文件打开模式 (Open Modes):
当我们打开一个文件时,可以指定它的用途,这些用途就是通过打开模式来控制的。这些模式通常通过
std::ios_base::openmode
std::ios::in
ifstream
std::ios::out
ofstream
std::ios::app
std::ios::ate
std::ios::trunc
ofstream
app
ate
std::ios::binary
\n
\r\n
std::ios::nocreate
std::ios::noreplace
这些模式可以通过位或运算符
|
std::ofstream outFile("log.txt", std::ios::out | std::ios::app);错误处理机制 (Error Handling):
文件操作是IO密集型任务,很容易受到外部因素(如磁盘空间、文件权限、文件损坏)的影响,所以错误处理显得尤为重要。
检查文件是否成功打开: 最直接也是最常用的方法。
std::ifstream inFile("nonexistent.txt");
if (!inFile.is_open()) { // 或者 if (!inFile)
std::cerr << "文件打开失败!" << std::endl;
// 可以根据具体情况抛出异常或退出
}流状态标志位:
fstream
good()
true
eof()
true
fail()
true
bad()
true
clear()
good()
fail()
eof()
rdstate()
setstate(state)
int value;
inFile >> value; // 尝试读取一个整数
if (inFile.fail()) {
std::cerr << "读取整数失败,可能输入格式不正确!" << std::endl;
inFile.clear(); // 清除错误标志,以便后续操作
// inFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 忽略当前行剩余内容
}异常处理:
fstream
std::ios_base::failure
exceptions()
std::ifstream inFile;
inFile.exceptions(std::ifstream::failbit | std::ifstream::badbit); // 在fail或bad状态时抛出异常
try {
inFile.open("data.txt");
// 进行读写操作
} catch (const std::ios_base::failure& e) {
std::cerr << "文件操作异常: " << e.what() << std::endl;
}这种方式可以集中处理错误,但需要注意异常开销和正确捕获。
我个人更倾向于结合
is_open()
fail()
高效的二进制文件读写在处理大量数据、自定义数据结构或者需要精确控制文件内容时显得尤为重要。与文本模式相比,二进制模式不进行任何字符编码转换,直接将内存中的字节序列写入文件或从文件中读取,这通常意味着更快的速度和更小的文件体积,因为它避免了额外的解析和格式化开销。
核心方法:read()
write()
C++的
fstream
read()
write()
istream& read(char* s, streamsize n);
n
s
ostream& write(const char* s, streamsize n);
s
n
这里的关键点是:
s
char*
n
char
int
float
struct
reinterpret_cast<char*>
示例:写入和读取自定义结构体
假设我们有一个表示学生信息的结构体:
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
// 定义一个简单的学生结构体
struct Student {
int id;
char name[20]; // 固定大小的字符数组,便于二进制读写
float score;
};
void writeBinaryFile() {
std::ofstream outFile("students.bin", std::ios::binary); // 以二进制模式打开文件写入
if (!outFile.is_open()) {
std::cerr << "错误:无法打开 students.bin 进行写入。" << std::endl;
return;
}
Student s1 = {101, "Alice", 95.5f};
Student s2 = {102, "Bob", 88.0f};
// 将结构体的内容按字节写入文件
outFile.write(reinterpret_cast<const char*>(&s1), sizeof(Student));
outFile.write(reinterpret_cast<const char*>(&s2), sizeof(Student));
outFile.close();
std::cout << "学生数据已成功写入 students.bin。" << std::endl;
}
void readBinaryFile() {
std::ifstream inFile("students.bin", std::ios::binary); // 以二进制模式打开文件读取
if (!inFile.is_open()) {
std::cerr << "错误:无法打开 students.bin 进行读取。" << std::endl;
return;
}
Student s;
std::cout << "从 students.bin 读取数据:" << std::endl;
// 循环读取直到文件末尾或发生错误
while (inFile.read(reinterpret_cast<char*>(&s), sizeof(Student))) {
std::cout << "ID: " << s.id << ", Name: " << s.name << ", Score: " << s.score << std::endl;
}
if (inFile.eof()) { // 正常读取到文件末尾
std::cout << "已读取到文件末尾。" << std::endl;
} else if (inFile.fail()) { // 读取过程中发生错误
std::cerr << "读取过程中发生错误!" << std::endl;
}
inFile.close();
}
// int main() {
// writeBinaryFile();
// readBinaryFile();
// return 0;
// }需要注意的挑战:
sizeof(Student)
sizeof(Student)
std::string
std::string
sizeof()
总的来说,二进制读写提供了极高的效率和控制力,但同时也要求开发者对数据在内存中的布局有更深入的理解,并考虑跨平台兼容性问题。
在我看来,选择文本模式还是二进制模式,是文件I/O中最基础也最关键的决策之一。它直接影响数据的存储方式、读取效率以及跨平台兼容性。
文本模式 (Text Mode):
\n
\r\n
\r\n
\n
<<
>>
.ini
.json
.xml
二进制模式 (Binary Mode):
核心区别总结:
说白了,文本模式关注的是“字符”和“行”的概念,它会根据操作系统的约定对某些特殊字符进行处理;而二进制模式关注的是“字节”,它只负责将内存中的字节原封不动地搬运到文件或从文件搬运到内存,不加任何干预。
选择建议:
我的建议是,如果你的数据是供人类阅读、编辑,或者需要与其他文本处理工具兼容,那么毫无疑问选择文本模式。而如果你的数据是机器生成、机器读取,需要最大程度地保持原始字节的精确性、追求效率,或者包含非文本信息(如图像像素),那么就应该选择二进制模式。在处理自定义结构体时,尽管二进制模式效率高,但务必注意字节序和数据对齐问题,必要时进行手动序列化/反序列化,以确保跨平台兼容性。
以上就是c++++如何读取和写入文件_c++文件读写操作详解的详细内容,更多请关注php中文网其它相关文章!
c++怎么学习?c++怎么入门?c++在哪学?c++怎么学才快?不用担心,这里为大家提供了c++速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号