标准C++操作文件方法总结

目录

1.核心头文件与基础类

2.文件打开模式

3.文件操作

3.1.文本文件操作

3.2.二进制文件操作

3.3.文件指针定位

3.4.错误处理

4.注意事项

5.总结


1.核心头文件与基础类

标准 C++ 中操作文件的核心是 <fstream> 头文件提供的流类,主要分为文本文件二进制文件两种操作方式。包含的头文件:

cpp 复制代码
#include <fstream>  // 核心:文件流
#include <iostream> // 控制台输出(辅助)
#include <string>   // 处理字符串(辅助)
using namespace std; // 简化代码,实际项目可按需省略

<fstream> 提供三个核心类:

类名 功能 继承自
ifstream 只读文件(输入流) istream
ofstream 只写文件(输出流) ostream
fstream 读写文件(双向流) iostream

如何写出高质量的函数?快来学习这些coding技巧

2.文件打开模式

通过 open() 函数或流对象构造函数指定打开模式(可组合使用,用 | 分隔):

模式常量 含义
ios::in 模式打开(ifstream 默认),文件不存在则失败
ios::out 模式打开(ofstream 默认),文件不存在则创建,存在则清空
ios::app 追加模式(写操作只在文件末尾),需配合 ios::out
ios::trunc 截断模式(清空文件内容),ios::out 默认包含此模式
ios::binary 二进制模式(默认是文本模式,文本模式会自动转换换行符:\n\r\n
ios::ate 打开后将文件指针定位到末尾(可重新定位指针)

3.文件操作

3.1.文本文件操作

文本文件以字符 / 字符串为单位读写,支持 <<(写)、>>(读)、getline()(读整行)等操作。

写文本文件:

cpp 复制代码
// 方式1:构造函数直接打开(推荐)
ofstream ofs("test.txt", ios::out); // ios::out 可省略(ofstream 默认)
if (!ofs.is_open()) { // 检查文件是否打开成功
    cerr << "文件打开失败!" << endl;
    return 1;
}

// 写入内容(支持多类型,如字符串、数字)
ofs << "姓名:张三" << endl;
ofs << "年龄:20" << endl;
ofs << "分数:95.5" << endl;

ofs.close(); // 显式关闭(析构函数也会自动关闭,建议显式关闭)

// 方式2:先创建对象,再用open()打开
ofstream ofs2;
ofs2.open("test_append.txt", ios::out | ios::app); // 追加模式
ofs2 << "追加的内容" << endl;
ofs2.close();

读文本文件:

cpp 复制代码
// 读文件(按空格/换行分割)
ifstream ifs("test.txt", ios::in);
if (!ifs.is_open()) {
    cerr << "文件打开失败!" << endl;
    return 1;
}

// 方式1:>> 运算符(自动跳过空格/换行,不适合含空格的整行)
string key;
string value;
while (ifs >> key >> value) { // 直到文件末尾
    cout << key << ":" << value << endl;
}
ifs.close();

// 方式2:getline() 读整行(适合含空格的内容)
ifstream ifs2("test.txt", ios::in);
string line;
while (getline(ifs2, line)) { // 逐行读取,直到EOF
    cout << line << endl;
}
ifs2.close();

// 方式3:get() 读单个字符
ifstream ifs3("test.txt", ios::in);
char ch;
while ((ch = ifs3.get()) != EOF) { // EOF:文件结束符
    cout << ch;
}
ifs3.close();

配合std::stringstream读取文件全部内容:

cpp 复制代码
#include <sstream>
#include <fstream>  // 核心:文件流
#include <string>

std::string  getFileData(const std::string& path)
{
    std::ifstream stream(path);
    std::stringstream  buffer;
    buffer << stream.rdbuf();
    return buffer.c_str();
}

3.2.二进制文件操作

二进制文件以字节为单位读写,需指定 ios::binary 模式,使用 write()(写)和 read()(读)成员函数。

写二进制文件:

cpp 复制代码
// 定义结构体(示例)
struct Student {
    char name[20]; // 用char数组避免string的二进制序列化问题
    int age;
    float score;
};

// 写二进制文件
Student s = {"李四", 21, 88.8};
ofstream ofs("student.bin", ios::out | ios::binary);
if (!ofs.is_open()) {
    cerr << "文件打开失败!" << endl;
    return 1;
}

// write(数据地址, 数据字节数)
ofs.write(reinterpret_cast<const char*>(&s), sizeof(Student));
ofs.close();

读二进制文件

cpp 复制代码
// 读二进制文件
Student s_read;
ifstream ifs("student.bin", ios::in | ios::binary);
if (!ifs.is_open()) {
    cerr << "文件打开失败!" << endl;
    return 1;
}

// read(数据地址, 数据字节数)
ifs.read(reinterpret_cast<char*>(&s_read), sizeof(Student));
cout << "姓名:" << s_read.name << endl;
cout << "年龄:" << s_read.age << endl;
cout << "分数:" << s_read.score << endl;
ifs.close();

3.3.文件指针定位

件指针(文件位置指示器)用于指定读写位置,核心函数:

函数 作用 适用流
seekg() 移动读指针位置 ifstream/fstream
seekp() 移动写指针位置 ofstream/fstream
tellg() 获取读指针当前位置 ifstream/fstream
tellp() 获取写指针当前位置 ofstream/fstream

参数格式:seekg(偏移量, 起始位置),起始位置可选:

  • ios::beg:文件开头(默认)
  • ios::cur:当前指针位置
  • ios::end:文件末尾

示例:修改二进制文件指定内容:

cpp 复制代码
fstream fs("student.bin", ios::in | ios::out | ios::binary);
if (!fs.is_open()) {
    cerr << "文件打开失败!" << endl;
    return 1;
}

// 将指针移动到age字段(跳过name的20字节)
fs.seekp(20, ios::beg); 
int new_age = 22;
fs.write(reinterpret_cast<const char*>(&new_age), sizeof(int));

// 重新定位指针,读取修改后的数据
fs.seekg(0, ios::beg);
Student s_modify;
fs.read(reinterpret_cast<char*>(&s_modify), sizeof(Student));
cout << "修改后年龄:" << s_modify.age << endl; // 输出22

fs.close();

3.4.错误处理

文件操作需检查状态,核心状态函数:

函数 含义
is_open() 检查文件是否成功打开(最常用)
eof() 检查是否到达文件末尾(End of File)
fail() 检查逻辑错误(如格式错误、文件不存在),无严重错误时可恢复
bad() 检查严重错误(如硬件故障、文件损坏),不可恢复
good() 检查流是否处于正常状态(!eof () && !fail () && !bad ())
clear() 重置流的状态标志(如处理 eof 后重置,继续操作)

示例:错误处理

cpp 复制代码
ifstream ifs("nonexist.txt", ios::in);
if (!ifs.is_open()) {
    cerr << "文件不存在!" << endl;
}

// 模拟读失败
string str;
ifs >> str;
if (ifs.fail()) {
    cerr << "读操作失败!" << endl;
    ifs.clear(); // 重置状态
}

ifs.close();

4.注意事项

  1. 文本模式 vs 二进制模式
    • 文本模式:自动转换换行符(Windows 下 \n\r\n,读取时反向转换);
    • 二进制模式:无转换,适合存储图片、视频、结构体等二进制数据。
  2. 字符串序列化 :二进制文件中避免直接写入 std::string(含指针),建议用固定长度 char 数组或手动序列化。
  3. 编码问题:文本文件读写中文时,需保证编码一致(如 UTF-8、GBK),避免乱码。
  4. 资源释放 :流对象析构时会自动关闭文件,但显式调用 close() 可及时释放文件句柄(尤其频繁操作文件时)。
  5. 路径问题 :文件路径支持相对路径(./test.txt)和绝对路径(C:/data/test.txt),注意 Windows 路径分隔符用 \\/

5.总结

标准 C++ 文件操作的核心是:

  1. 选择合适的流类(ifstream/ofstream/fstream);
  2. 指定正确的打开模式(文本 / 二进制、读 / 写 / 追加);
  3. 用对应方法读写(文本:<</>>/getline();二进制:write()/read());
  4. 检查文件状态并处理错误;
  5. 按需定位文件指针,完成复杂读写。
相关推荐
编码浪子2 分钟前
Rust 1.95 稳定版解读与生态新动向
开发语言·后端·rust
asdzx674 分钟前
告别手动校对:使用 Python 对比两个 PDF 文档的差异
开发语言·python·pdf
Rust研习社5 分钟前
Rust 操作 Redis 从入门到生产级应用
开发语言·redis·后端·rust
xyq202414 分钟前
Memcached stats items 命令详解
开发语言
Evand J15 分钟前
【MATLAB例程】多传感器协同DOA目标跟踪与EKF滤波,输出动态目标轨迹、轨迹误差对比分析
开发语言·matlab·目标跟踪·滤波·定位·导航
csbysj202016 分钟前
《jEasyUI 自定义分页》
开发语言
初心未改HD17 分钟前
Go语言Context深度解析与工程实践
开发语言·golang
大袁同学18 分钟前
【进程间通信】:洞穿边界修管道,映射内存渡进程
linux·c++·管道·进程间通信·ipc
ximu_polaris18 分钟前
设计模式(C++)-行为型模式-责任链模式
c++·设计模式·责任链模式
SilentSamsara21 分钟前
Python 内存管理:引用计数、循环垃圾回收与内存泄漏排查
开发语言·vscode·python·青少年编程·pycharm