标准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. 按需定位文件指针,完成复杂读写。
相关推荐
浔川python社2 小时前
《C++ 小程序编写系列》(第四部):实战:简易图书管理系统(类与对象篇)
java·开发语言·apache
虾..2 小时前
Linux 进程池小程序
linux·c++·小程序
浔川python社2 小时前
《C++ 小程序编写系列》(第五部):实战:多角色图书管理系统(继承与多态篇)
开发语言·c++
CC.GG2 小时前
【Qt】信号和槽
开发语言·数据库·qt
是席木木啊2 小时前
基于MinIO Java SDK实现ZIP文件上传的方案与实践
java·开发语言
一起养小猫2 小时前
《Java数据结构与算法》第四篇(四):二叉树的高级操作查找与删除实现详解
java·开发语言·数据结构·算法
ALex_zry2 小时前
C++20/23标准对进程间共享信息的优化:从传统IPC到现代C++的演进
开发语言·c++·c++20
IMPYLH2 小时前
Lua 的 OS(操作系统) 模块
开发语言·笔记·后端·游戏引擎·lua
YGGP3 小时前
【Golang】LeetCode 287. 寻找重复数
开发语言·leetcode·golang