【问题标题】:C++ writing to a Binary file with ofstreamC++ 使用 ofstream 写入二进制文件
【发布时间】:2025-12-28 01:55:06
【问题描述】:

对于我正在开发的小文件格式,我需要将 519 字节的标头输出到文件中。我对整个 ofstream 概念有点陌生。虽然我在阅读 Truevision Targa 文件的标题方面有一些经验。但是输出是我非常熟悉的东西。

所以基本上,这是我的问题。

我打开了一个ofstream的实例,我需要像这样输出一个header:

typedef struct header {
    char      version;   // offset 0, length 1
    short int width;     // offset 1, length 2
    short int height;    // offset 3, length 2
    short int pathlen;   // offset 5, length 2
    char      desc[512]; // offset 7, length 512
} fileHeader;

现在我需要在文件的前 519 个字节中获取所有这些内容,其余内容各不相同,我将如何将此标头复制到我的文件中?

我最好希望使用 ofstream 类来执行此操作,但我也可以使用原始 C 库。我已经在这里呆了 2 个小时了,但我还没有到任何地方,尝试在 Google 上搜索也没有多大帮助。

【问题讨论】:

    标签: c++ binary ofstream


    【解决方案1】:
    std::ofstream& operator<<(std::ofstream& out, const header& myheader) {
        out.write((char*)&myheader.version, sizeof(myheader.version));
        out.write((char*)&myheader.width, sizeof(myheader.width));
        out.write((char*)&myheader.height, sizeof(myheader.height));
        out.write((char*)&myheader.pathlen, sizeof(myheader.pathlen));
        out.write((char*)&myheader.desc, sizeof(myheader.desc));
        return out;
    }
    std::ifstream& operator>>(std::ifstream& in, header& myheader) {
        in.read((char*)&myheader.version, sizeof(myheader.version));
        in.read((char*)&myheader.width, sizeof(myheader.width));
        in.read((char*)&myheader.height, sizeof(myheader.height));
        in.read((char*)&myheader.pathlen, sizeof(myheader.pathlen));
        in.read((char*)&myheader.desc, sizeof(myheader.desc));
        return in;
    }
    
    int main() {
        std::cout << fileHeader << '\n';
        std::cin >> fileHeader;
        return 0;
    }
    

    由于您没有指针,因此相当容易! (请注意,这只适用于窄流)
    另一个用文本和动态内存/指针/等显示事物的示例

    class thing {
        std::string name;
        int height;
        friend std::ofstream& operator<<(std::ofstream& out, const thing & myheader);
        friend std::ifstream& operator>>(std::ifstream& in, thing & myheader);
    public: 
        thing() {}
    };
    
    std::ofstream& operator<<(std::ofstream& out, const thing & myheader) {
        thing << name.size() << ' ';
        thing.write(&name[0], name.size()) << ' ' << height;
    } 
    std::ifstream& operator>>(std::ifstream& in, thing & myheader) {
        int size;
        in >> size;
        myheader.name.resize(size);
        in.read(&myheader.name[0], name.size());
        return in >> myheader.height;        
    } 
    

    【讨论】:

    • 如果结构的格式不正确,这种转换可能会导致麻烦。
    • 感谢您的回答,但我想解释一下它是如何工作的。我如何确保数据以正确的顺序写入(版本优先,然后是宽度等)。此外,不知何故,该功能对我来说看起来不正确。感觉有些不对劲。
    • 你(都)是对的,我忘了填充。您的结构将 not 在 RAM 中为 519 字节,仅在磁盘上。 (在 Windows 上为 520 字节)已修复。 @user1019020:它们本来是有序的,但是在版本字节之后会有一个废话字节。
    • 如果您担心打包和字对齐,建议您对结构的每个成员调用 read 和 write,而不是一次性调用全部。从您的偏移量来看,您似乎想要紧密打包数据。您的 char 很可能已填充到架构的短 int 边界。
    • @MooingDuck 是的,我尝试了你的方法,然后读回我的文件,宽度突然从 20 变为 5192 或其他东西。我会试试你的新建议。 :)