C++写文件笔记

C++写文件笔记

C++二进制文件写入

二进制文件写入是C++高频操作,相比文本文件,具有体积小、读写快、数据完整的优势,适用于序列化、配置保存等场景。以下为两种核心写入方式(C语言风格、C++原生风格),主目录仅保留最简示例,进阶操作(如指针定位)放在对应子章节,便于分层学习。

1. C语言风格FILE*写入(兼容适配首选)

1.1 FILE*基础:写文件

适配C/C++混合、嵌入式、老项目,依赖<cstdio>,需手动管理文件指针,主目录仅展示"打开-写入-关闭"最简流程。

cpp 复制代码
#include <cstdio>
using namespace std;

struct Student { char name[20]; int age; float score; };

int main() {
    // 1. 打开二进制文件(wb=二进制写入,不存在则创建,存在则覆盖)
    FILE* fp = fopen("test_fwrite.bin", "wb");
    if (!fp) return 1; // 校验打开结果

    // 2. 最简写入:基础数据+自定义结构体
    int num = 123456;
    Student stu = {"ZhangSan", 20, 95.5f};
    fwrite(&num, sizeof(int), 1, fp);
    fwrite(&stu, sizeof(stu), 1, fp);

    // 3. 关闭文件,释放资源
    fclose(fp);
    return 0;
}

所用核心函数原型及参数解释(最简版)

  • fopen :FILE* fopen(const char* filename, const char* mode);,参数:文件路径、打开模式("wb"=二进制写入)。
  • fwrite :size_t fwrite(const void* ptr, size_t size, size_t count, FILE* stream);,参数:数据地址、单个元素字节数、元素个数、文件指针。
  • fclose :int fclose(FILE* stream);,参数:文件指针,功能:释放资源。
1.2 FILE*进阶:文件指针定位(fseek用法)

在最简写入基础上,新增fseek指针定位功能,实现指定位置写入/覆盖,适用于灵活调整写入位置的场景。

<cstdio> 复制代码
>using namespace std;

int main() {
    FILE* fp = fopen("test_fwrite_seek.bin", "wb");
    if (!fp) return 1;

    int num1 = 123456, num2 = 654321;
    // 先写入num1,指针自动移动到文件末尾
    fwrite(&num1, sizeof(int), 1, fp);

    // 定位指针到文件开头(SEEK_SET=文件起始),覆盖写入num2
    fseek(fp, 0, SEEK_SET);
    fwrite(&num2, sizeof(int), 1, fp);

    // 定位指针到当前位置(SEEK_CUR),向后偏移4字节,写入新数据
    fseek(fp, 4, SEEK_CUR);
    int num3 = 7890;
    fwrite(&num3, sizeof(int), 1, fp);

    fclose(fp);
    return 0;
}

进阶函数(fseek)原型及参数解释

  • fseek :int fseek(FILE* stream, long int offset, int origin);
    参数1(stream):文件指针;
    参数2(offset):偏移量(正数向后移,负数向前移);
    参数3(origin):偏移基准(SEEK_SET=文件起始、SEEK_CUR=当前位置、SEEK_END=文件末尾)。

2. 标准ofstream流写入(C++原生首选)

2.1 ofstream基础:写文件

纯C++环境、跨平台首选`,ofstream类封装,无需手动管理指针,主目录仅展示"打开-写入-关闭"最简流程。

cpp 复制代码
#include<fstream>
using namespace std;

struct Student { char name[20]; int age; float score; };

int main() {
    // 1. 打开二进制文件(ios::binary=二进制,ios::out=写入)
    ofstream ofs("test_fstream.bin", ios::binary | ios::out);
    if (!ofs.is_open()) return 1; // 校验打开结果

    // 2. 最简写入:基础数据+自定义结构体
    int num = 123456;
    Student stu = {"LiSi", 21, 92.0f};
    ofs.write((char*)&num, sizeof(num));
    ofs.write((char*)&stu, sizeof(stu));

    // 3. 关闭文件流
    ofs.close();
    return 0;
}

所用核心方法原型及参数解释(最简版)

  • ofstream 构造函数 :ofstream(const char* filename, ios_base::openmode mode);,参数:文件路径、打开模式。
  • ofstream::is_open :bool is_open() const;,返回值:true=打开成功。
  • ofstream::write :ostream& write(const char* ptr, streamsize count);,参数:数据地址(强转char*)、写入字节数。
  • ofstream::close :void close();,功能:释放文件资源。
2.2 ofstream底层流进阶:指针定位与灵活写入

依托ostream基类特性,在ofstream最简写入基础上,新增seekp指针定位、分块写入等进阶操作,体现灵活性与可扩展性。

cpp<fstream> 复制代码
>using namespace std;

int main() {
    ofstream ofs("test_ostream_advance.bin", ios::binary | ios::out);
    if (!ofs) return 1;

    // 1. 零散数据拼接写入
    char header[] = "BIN_FILE";
    int count = 3;
    float a = 10.5f, b = 20.8f, c = 30.2f;
    ofs.write(header, sizeof(header));
    ofs.write((char*)&count, sizeof(count));
    ofs.write((char*)&a, sizeof(a));

    // 2. seekp指针定位:定位到文件开头,覆盖写入数据总大小
    ofs.seekp(0, ios::beg);
    int total_size = sizeof(header) + sizeof(count) + sizeof(a) + sizeof(b) + sizeof(c);
    ofs.write((char*)&total_size, sizeof(total_size));

    // 3. 大文件分块写入(避免占用过多内存)
    const int BUF_SIZE = 1024;
    char big_data[1024 * 10];
    for (int i = < 1024*10; i++) big_data[i] = i % 256;
    int pos = 0, total = sizeof(big_data);
    while (pos < total) {
        int write_size = min(BUF_SIZE, total - pos);
        ofs.write(big_data + pos, write_size);
        pos += write_size;
    }

    ofs.close();
    return 0;
}

进阶方法(seekp)原型及参数解释

  • ofstream::seekp :ostream& seekp(streampos pos); 或 ostream& seekp(streamoff off, ios_base::seekdir dir);
    参数1(pos/off):指针位置(绝对位置pos,或相对偏移off);
    参数2(dir):偏移基准(ios::beg=文件起始、ios::cur=当前位置、ios::end=文件末尾);
    功能:调整输出流指针,实现指定位置写入。

FILE*与ofstream对比建议

写入方式(含进阶) 优势 劣势 推荐场景
FILE*写入 兼容强、性能高、底层可控,支持fseek定位 C风格、需手动管理指针 嵌入式、混合编译、老项目
ofstream写入 C++原生、跨平台、安全简洁,支持seekp定位与分块 性能略低于fwrite 日常项目、新手、纯C++环境,需灵活写入场景

选型总结:新手优先ofstream(最简版),兼容场景用FILE*(最简版);

相关推荐
Li_RuiQi15 小时前
DAgger方法演进_独立学习笔记
笔记·学习·计算机视觉
CodeYp201915 小时前
第15讲:二叉搜索树
开发语言·c++·二叉搜索树
pipixia2003316 小时前
C++继承面试四连问:内存叠加、私有继承、sizeof、权限重映射
c++·面试·嵌入式·继承·面向对象·对象模型
牵猫散步的鱼儿19 小时前
C++ 内存分区
c++
choumin19 小时前
C++ 标准容器为什么不能存引用
c++·容器·引用类型
Li_RuiQi19 小时前
DAgger与交互式模仿学习_ACT学习笔记
笔记·学习
谙弆悕博士19 小时前
用 C 写了个 Windows 聊天室,踩了几个多线程和控制台的坑
c语言·开发语言·c++·windows·网络编程·聊天室
He BianGu19 小时前
【笔记】C# 中BindingFlags的详细作用
笔记·c#
AI视觉网奇19 小时前
turtle 入门教程笔记
笔记
stolentime20 小时前
CF2277E Tree Guessing题解
c++·算法·贪心算法·交互·ad-hoc