std::当在256字节边界上写入整数时,流的奇怪行为

std::ofstream weird behavior when writing integers on byte border from 256

本文关键字:字节 当在 边界 std 整数      更新时间:2023-10-16

Tring创建了一个二进制文件格式,但行为怪异。

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(以及5121024..(?

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

通过使用格式化的插入运算符<<并给它一个const char*,您告诉流您给它的是一个C字符串,即一个以null结尾的字节序列,将被解释为字符。

但事实并非如此。

事实上,任何带有"null"组件的long long值(任何设置为零的字节(都将终止该格式化插入。

否则<<怎么知道何时停止?

您应该使用outputFile.write(...),因为这就是"原始"字节直接插入流的方式。

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

请注意,除非您在文件中写入一些指示符,以告诉读者写入了哪些endianness值,否则您将永远无法再次明确地读取它们。(然而,对于一个幼稚的、不可移植的应用程序来说,这可能不是一个考虑因素。(

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

Little Endian中的255将被转换为0xff 0 0 0,因此它只写入0xff

256将被转换为0 0x01 0,因此它被认为是一个空字符串,因为它以0开头。

257将被转换为0x01 0x01 0,因此它将被正确打印。

第一个字节为0的任何数字(例如512768、1024都是256的乘积(都不会用您的方法打印(在Windows和Linux等小终结点机器上(,因为第一个字节是0。

相关文章: