将十六进制数据输出到文件的正确方法是什么?

| 我已经读过关于ѭ0的内容,但是我对此有一些疑问 (1)我使用
output.open(\"BWhite.bmp\",ios::binary);
将文件流
output
定义为十六进制输出文件流,因为这样做了,这会使
output<<
操作中的
hex
参数变得多余吗? (2) 如果我有一个整数值,我想存储在文件中,并使用以下代码:
int i = 0;
output << i;
我会以小端或大端存储吗?耐久性会根据在哪个计算机上执行或编译程序而改变? 此值的大小是否取决于运行它的计算机?我需要使用十六进制参数吗? (3)是否可以将原始十六进制数字输出到文件?如果我希望文件的十六进制数字为43,应该怎么用?
output << 0x43
output << hex << 0x43
都输出ASCII 4,然后输出ASCII 3。 输出这些十六进制数字的目的是为.bmp文件创建标题。     
已邀请:
        格式化输出运算符
<<
仅用于:格式化输出。它用于字符串。 这样,“ 9”流操纵器告诉流以数字格式输出为十六进制的字符串。 如果要输出原始二进制数据,请仅使用未格式化的输出函数,例如
basic_ostream::put
basic_ostream::write
。 您可以这样输出一个int:
int n = 42;
output.write(&n, sizeof(int));
此输出的字节序将取决于体系结构。如果您希望拥有更多控制权,建议采取以下措施:
int32_t n = 42;
char data[4];
data[0] = static_cast<char>(n & 0xFF);
data[1] = static_cast<char>((n >> 8) & 0xFF);
data[2] = static_cast<char>((n >> 16) & 0xFF);
data[3] = static_cast<char>((n >> 24) & 0xFF);
output.write(data, 4);
无论平台的字节顺序如何,此示例都将输出32位整数作为little-endian。但是,如果签署了
char
,请小心地将其转换回去。     
        你说   \“有没有一种方法可以将原始的十六进制数字输出到文件?如果我希望文件具有十六进制数字43,我应该使用什么?” \“原始十六进制数字\”将取决于您对位集合所做的解释。考虑以下:
 Binary  :    0 1 0 0 1 0 1 0
 Hex     :    4 A
 Octal   :    1 1 2
 Decimal :    7 4
 ASCII   :    J
以上所有都代表相同的数值,但是我们对它的解释不同。 因此,您只需要将数据存储为二进制格式,即以数字表示的确切位模式。 编辑1 当您以文本模式打开文件并在其中写入数字时,例如,当您写入
74
时(如上例所示),该文件将存储为两个ASCII字符
\'7\'
\'4\'
。为避免这种情况,请以二进制模式
ios::binary
打开文件,并用
write ()
进行写入。检查http://courses.cs.vt.edu/~cs2604/fall00/binio.html#write     
           输出这些十六进制数字的目的是为.bmp文件创建标题。 您似乎对文件的工作原理有很大的误解。 流运算符“ 8”生成文本(人类可读的输出)。 .bmp文件格式是一种二进制格式,不能被人工读取(会是但不是很好,如果没有工具,我不会阅读)。 您真正想要做的是生成二进制输出并将其放置在文件中:
char   x = 0x43;
output.write(&x, sizeof(x));
这会将十六进制值为0x43的一个字节数据写入输出流。这是您想要的二进制表示形式。   我会以小端或大端存储吗?耐久性会根据在哪个计算机上执行或编译程序而改变? 都不;您将再次输出文本(不是二进制数据)。
int i = 0;
output.write(reinterpret_cast<char*>(&i), sizeof(i)); // Writes the binary representation of i
在这里,您确实需要担心整数值的字节序(和大小),并且这取决于运行应用程序的硬件。对于值0,没有太多担心字节序的问题,但是您应该担心整数的大小。 我将一些断言放入我的代码中,以验证该体系结构对于该代码是否正确。然后让人们担心他们的体系结构是否不符合要求:
int test = 0x12345678;
assert((sizeof(test) * CHAR_BITS == 32) && \"BMP uses 32 byte ints\");
assert((((char*)&test)[0] == 0x78) && \"BMP uses little endian\");
有一系列功能可以帮助您提高耐力和体型。 http://www.gnu.org/s/hello/manual/libc/Byte-Order.html   函数:uint32_t htonl(uint32_t hostlong)       此函数将uint32_t整数hostlong从主机字节顺序转换为网络字节顺序。
// Writing to a file
uint32_t hostValue = 0x12345678;
uint32_t network   = htonl(hostValue);
output.write(&network, sizeof(network));

// Reading from a file
uint32_t network;
output.read(&network, sizeof(network);
uint32_t hostValue = ntohl(network);    // convert back to platform specific value.

// Unfortunately the BMP was written with intel in-mind
// and thus all integers are in liitle-endian.
// network bye order (as used by htonl() and family) is big endian.
// So this may not be much us to you.
最后一件事。当您以二进制格式ѭ26open打开文件时,除了如何对待
end of line sequence
以外,其他任何操作都没有。当文件为二进制格式时,输出不会被修改(输入流中的内容就是写入文件的内容)。如果将流保留为文本模式,则\'\\ n \'字符将转换为行末尾(定义行尾的OS特定字符集)。由于您正在编写二进制文件,因此您绝对不希望干扰所写的字符,因此二进制文件是正确的格式。但这不会影响您在流上执行的任何其他操作。     

要回复问题请先登录注册