从256的字节边界写入整数时std :: ofstream怪异的行为

时间:2018-11-01 15:13:58

标签: c++ c++11 ofstream

试图创建二进制文件格式,但是行为异常。

    std::ofstream outputFile;
    outputFile.open (PATH, std::ios_base::out | std::ios_base::binary |
    std::ios_base::app);
    unsigned long long int timer3 = 255;
    outputFile <<reinterpret_cast<const char *>(&timer3);
    timer3 = 256;
    outputFile <<reinterpret_cast<const char *>(&timer3);
    timer3 = 257;
    outputFile <<reinterpret_cast<const char *>(&timer3);
    timer3 = 258;
    outputFile <<reinterpret_cast<const char *>(&timer3);

二进制输出文件仅包含(以十六进制表示)         FF 01 01 02 01

FF- 255

01 01- 257

02 01 -258

为什么它公然无视256(和512、1024 ..)?

将整数逐个整数写入二进制的最佳方法是什么?

2 个答案:

答案 0 :(得分:4)

通过使用格式化的插入运算符<<并将其赋予const char*,您将告诉流为其提供了C字符串,即,以空终止的字节序列被解释为字符。

但这不是真的。

实际上,任何带有“空”成分(任何字节设置为零)的long long值都将终止格式化的插入。

<<还能知道何时停止?

您应该改用outputFile.write(...),因为这是将“原始”字节直接插入流中的方式。

outputFile.write(reinterpret_cast<const char *>(&timer3), sizeof(timer3));

请注意,除非您在文件中写入一些指示符以告知读者这些值是 endianness 写的,否则您将永远无法再明确地读出它们。 (但是,对于天真,不可移植的应用程序,这可能不是考虑因素。)

答案 1 :(得分:1)

使用流运算符(char*)将<<写入文件时,它将在第一个终止NULL(= 0)处停止。

Little-Endian中的

255将转换为 0xff 0 0 0 ,因此它仅写入 0xff

256将被转换为 0 0x01 0 ,因此它被认为是空字符串,因为它从0开始。

257将转换为 0x01 0x01 0 ,因此可以正常打印。

第一个字节为0的任何数字(例如512、768、1024均为256的倍数)将不会用您的方法打印(在Windows和Linux等Little Endian机器上),因为第一个字节为0