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*(最简版);

相关推荐
WL学习笔记6 分钟前
日期类(C++)
开发语言·c++·日期类实现
H.莓飛1 小时前
【C++】命名空间、缺省参数、函数重载与引用
linux·开发语言·c++·visual studio
2501_926978331 小时前
给自指系统接一个外部锚 —— 一个关于「用 AI 观察自己」的方法
人工智能·经验分享·笔记·机器学习·ai写作
汉克老师2 小时前
GESP2026年9月认证C++八级( 第一部分选择题(1~7题)精讲
c++·gesp·小学生·学c++编程
郝学胜_神的一滴4 小时前
C++ Templates 06:搞懂模板代码的三种组织方式
c++·visual studio
C++ 老炮儿的技术栈4 小时前
sizeof操作符
c语言·c++·人工智能·mfc·c
沫璃染墨4 小时前
《Linux工程实践篇(一):认识设计模式——从日志系统看策略模式》
linux·c++·安全·设计模式·策略模式
wuminyu4 小时前
ForkJoinPool内部WorkQueue的Lock-Free数组操作以及并发任务窃取原理剖析
java·linux·c语言·jvm·c++
Zguigo5 小时前
【CUDA8】第一个CUDA C++ Kernel --vector add
java·开发语言·c++
-Marks-5 小时前
【C++编程】STL容器(二)--- vector底层模拟实现(常用接口实现 | 扩容机制 | 深浅拷贝 | 迭代器失效)
开发语言·c++·vector·内存管理·迭代器失效·vector底层模拟实现