C++ 中文件 IO 操作详解

在C++中,文件操作是通过流(stream)来实现的。标准库提供了三种主要的文件流类来处理文件IO操作:

  • ofstream:用于写入文件(output file stream)
  • ifstream:用于读取文件(input file stream)
  • fstream:用于读写文件(file stream)

这些类都继承自C++标准库中的流基类,提供了统一的接口来操作文件。

一、文件流类的基本使用

打开文件

打开文件是进行文件操作的第一步。每个流类都提供了open()方法,也可以在构造函数中直接指定文件名:

cpp 复制代码
#include <fstream>

// 使用构造函数打开文件
std::ofstream outFile("example.txt");  // 写入模式
std::ifstream inFile("example.txt");   // 读取模式
std::fstream ioFile("example.txt", std::ios::in | std::ios::out);  // 读写模式

// 或者使用open()方法
std::ofstream outFile2;
outFile2.open("example.txt");
文件打开模式

文件打开模式可以通过位操作符|组合使用:

  • std::ios::in:读取模式
  • std::ios::out:写入模式(默认会截断文件)
  • std::ios::app:追加模式
  • std::ios::ate:打开后定位到文件末尾
  • std::ios::trunc:打开时截断文件(删除原有内容)
  • std::ios::binary:二进制模式
检查文件是否成功打开

在进行文件操作前,应该检查文件是否成功打开:

cpp 复制代码
if (!outFile.is_open()) {
    std::cerr << "无法打开文件!" << std::endl;
    return 1;
}

// 或者更简洁的方式
if (!outFile) {
    std::cerr << "文件打开失败!" << std::endl;
    return 1;
}

二、写入文件(ofstream)

ofstream类用于向文件写入数据,它继承了ostream的功能,因此可以使用<<操作符:

cpp 复制代码
#include <fstream>
#include <iostream>

int main() {
    // 创建并打开文件
    std::ofstream outFile("data.txt");
    
    if (outFile.is_open()) {
        // 写入文本数据
        outFile << "Hello, World!" << std::endl;
        outFile << "这是一个测试文件。" << std::endl;
        
        // 写入数值数据
        int number = 42;
        double pi = 3.14159;
        outFile << "Number: " << number << ", Pi: " << pi << std::endl;
        
        // 写入自定义数据
        std::string name = "Doubao";
        outFile << "Name: " << name << std::endl;
        
        // 关闭文件
        outFile.close();
        std::cout << "文件写入成功!" << std::endl;
    } else {
        std::cerr << "无法打开文件进行写入!" << std::endl;
    }
    
    return 0;
}

三、读取文件(ifstream)

ifstream类用于从文件读取数据,它继承了istream的功能,因此可以使用>>操作符或getline()方法:

cpp 复制代码
#include <fstream>
#include <iostream>
#include <string>

int main() {
    // 打开文件
    std::ifstream inFile("data.txt");
    
    if (inFile.is_open()) {
        // 逐行读取
        std::string line;
        while (std::getline(inFile, line)) {
            std::cout << line << std::endl;
        }
        
        // 关闭文件
        inFile.close();
    } else {
        std::cerr << "无法打开文件进行读取!" << std::endl;
    }
    
    return 0;
}
读取不同类型的数据
cpp 复制代码
#include <fstream>
#include <iostream>
#include <string>

int main() {
    std::ifstream inFile("data.txt");
    
    if (inFile.is_open()) {
        // 读取字符串
        std::string text;
        inFile >> text;
        std::cout << "读取的文本: " << text << std::endl;
        
        // 读取整数
        int number;
        inFile >> number;
        std::cout << "读取的整数: " << number << std::endl;
        
        // 读取浮点数
        double pi;
        inFile >> pi;
        std::cout << "读取的浮点数: " << pi << std::endl;
        
        // 读取整行(包括空格)
        std::string fullLine;
        std::getline(inFile, fullLine);  // 清除缓冲区中的换行符
        std::getline(inFile, fullLine);
        std::cout << "读取的整行: " << fullLine << std::endl;
        
        inFile.close();
    }
    
    return 0;
}

四、读写文件(fstream)

fstream类结合了ifstreamofstream的功能,可以同时进行读写操作:

cpp 复制代码
#include <fstream>
#include <iostream>
#include <string>

int main() {
    // 打开文件进行读写,不截断
    std::fstream ioFile("data.txt", std::ios::in | std::ios::out);
    
    if (ioFile.is_open()) {
        // 读取现有内容
        std::string content;
        std::getline(ioFile, content);
        std::cout << "读取的内容: " << content << std::endl;
        
        // 定位到文件末尾进行追加
        ioFile.seekp(0, std::ios::end);
        ioFile << "这是追加的内容" << std::endl;
        
        // 定位到文件开头重新读取
        ioFile.seekg(0, std::ios::beg);
        while (std::getline(ioFile, content)) {
            std::cout << content << std::endl;
        }
        
        ioFile.close();
    }
    
    return 0;
}

五、文件定位和状态检查

文件定位

可以使用以下方法控制文件指针位置:

  • tellg():返回输入位置
  • tellp():返回输出位置
  • seekg():设置输入位置
  • seekp():设置输出位置
状态检查

流状态可以通过以下方法检查:

  • good():检查流是否正常
  • eof():检查是否到达文件末尾
  • fail():检查是否发生非致命错误
  • bad():检查是否发生致命错误
  • clear():清除错误标志

六、二进制文件操作

对于二进制文件,需要使用std::ios::binary模式:

cpp 复制代码
#include <fstream>
#include <iostream>

int main() {
    // 写入二进制数据
    {
        std::ofstream outFile("binary.bin", std::ios::binary);
        int numbers[] = {1, 2, 3, 4, 5};
        outFile.write(reinterpret_cast<char*>(numbers), sizeof(numbers));
    }
    
    // 读取二进制数据
    {
        std::ifstream inFile("binary.bin", std::ios::binary);
        int readNumbers[5];
        inFile.read(reinterpret_cast<char*>(readNumbers), sizeof(readNumbers));
        
        for (int i = 0; i < 5; ++i) {
            std::cout << readNumbers[i] << " ";
        }
        std::cout << std::endl;
    }
    
    return 0;
}

七、文件操作的最佳实践

  1. 始终检查文件是否成功打开
  2. 使用RAII原则(资源获取即初始化)管理文件资源
  3. 明确指定文件打开模式
  4. 对于大文件,考虑分块读取或写入
  5. 处理可能的异常情况
  6. 使用std::endl会刷新缓冲区,如需提高性能可使用\n
  7. 对于二进制文件,使用read()write()方法

通过掌握这些文件IO操作,可以在C++中有效地处理各种文件读写任务。

相关推荐
浪裡遊5 分钟前
React Hooks全面解析:从基础到高级的实用指南
开发语言·前端·javascript·react.js·node.js·ecmascript·php
彭祥.30 分钟前
Jetson边缘计算主板:Ubuntu 环境配置 CUDA 与 cudNN 推理环境 + OpenCV 与 C++ 进行目标分类
c++·opencv·分类
lzb_kkk1 小时前
【C++】C++四种类型转换操作符详解
开发语言·c++·windows·1024程序员节
好开心啊没烦恼1 小时前
Python 数据分析:numpy,说人话,说说数组维度。听故事学知识点怎么这么容易?
开发语言·人工智能·python·数据挖掘·数据分析·numpy
简佐义的博客2 小时前
破解非模式物种GO/KEGG注释难题
开发语言·数据库·后端·oracle·golang
程序员爱钓鱼2 小时前
【无标题】Go语言中的反射机制 — 元编程技巧与注意事项
开发语言·qt
Frank学习路上2 小时前
【IOS】XCode创建firstapp并运行(成为IOS开发者)
开发语言·学习·ios·cocoa·xcode
2301_805054562 小时前
Python训练营打卡Day59(2025.7.3)
开发语言·python
胖大和尚3 小时前
clang 编译器怎么查看在编译过程中做了哪些优化
c++·clang