Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;32位到64位的二进制写入/读取_C++_File_File Io_Stream_32bit 64bit - Fatal编程技术网

C++ C++;32位到64位的二进制写入/读取

C++ C++;32位到64位的二进制写入/读取,c++,file,file-io,stream,32bit-64bit,C++,File,File Io,Stream,32bit 64bit,如果您有一个二进制输出流,并将整数写入32位Windows计算机上的文件。那么,您是否能够在64位Windows计算机上从同一文件中读取相同的整数 我的猜测是否定的。因为32位计算机上的整数是4字节,而64位计算机上的整数是8字节 下面的代码也可以工作,而文件必须能够从64位和32位计算机读取和写入,无论操作系统、计算机体系结构和数据类型如何。如果不是的话,当文件必须是二进制格式时,如何才能做到这一点呢 书写 阅读 虽然几乎所有现代平台(32位和64位)上的int都是4字节,但它的大小不能保证。

如果您有一个二进制输出流,并将整数写入32位Windows计算机上的文件。那么,您是否能够在64位Windows计算机上从同一文件中读取相同的整数

我的猜测是否定的。因为32位计算机上的整数是4字节,而64位计算机上的整数是8字节

下面的代码也可以工作,而文件必须能够从64位和32位计算机读取和写入,无论操作系统、计算机体系结构和数据类型如何。如果不是的话,当文件必须是二进制格式时,如何才能做到这一点呢

书写 阅读
虽然几乎所有现代平台(32位和64位)上的
int
都是4字节,但它的大小不能保证。因此,对于将数据序列化到文件或其他二进制流中,您应该更喜欢C++11中引入的标题中的固定宽度整数类型(某些编译器在C++03中支持该类型):

虽然考虑到上面的固定宽度整数,这听起来很愚蠢,但如果您想将假设的整个结构存储在某个库的某个版本中,这可能会很有用。示例:
glm
中的
vec4
被记录为包含四个浮点数,因此在序列化此结构时,最好静态地检查它,以便捕获将来的库更改(不太可能,但可能)


<强>另一个非常重要的事情是积分类型的子集,它在平台之间变化。< /强>大多数现代x86桌面平台的编译器使用整数类型的小Endiad,所以我更倾向于使用二进制文件格式;但是如果平台使用大字节,则需要转换它(反转字节顺序)。

不能保证C++中int的大小。您所知道的是,它至少与短int一样大,而不大于长int。编译器可以在这些约束内自由选择适当的大小。虽然大多数人会选择32位作为int的大小,但有些人不会

如果您知道您的类型始终为32位,则可以使用int32\u t类型

include <stdint.h>
包括

以获取此类型。据我所知,在32位和64位Windows系统上,sizeof(int)==4。它是
长的
和指针类型的变化。@JoeZ-Mhm,这不是我在堆栈溢出问题上读到的内容,关于
大小的
。@Vallentin:如果您使用的是C++11,只需包含
并使用正确的固定宽度整数类型(例如
int32\t
).有一个标准和实施的解释。通过在两个平台上打印sizeof(int)来检查实现要比在互联网上查找答案快得多。如果你打印sizeof(int),你会发现,正如JoeZ所说,在两种平台上,从VS8到VS12,它都是4。Vallentin:从16位MS-DOS到32位确实有一个
int
的大小变化。从32位到64位并没有改变。正如@Zeta所说,您可以使用固定宽度类型使代码中的宽度假设更加清晰。顺便说一句,另一件需要注意的事情是,32位和64位结构布局可能因对齐规则不同而不同。所以要小心。你如何控制流的endianess?endianess在你的代码中被考虑。在您发布的代码中,您将整数指针解释为char指针,然后根据编译器/平台如何布局整数类型将其读取为一系列字节。因此,关键是检测平台的endianess(我不知道如何做),并定义文件格式的endianess(您可以选择其中一种;我建议使用little endian),如果它们不匹配,则使用helper函数反转字节。这可能类似于
charb[4];b[3]=*p++;b[2]=*p++;b[1]=*p++;b[0]=*p;ofs.write(b,4)看到这个:@Vallentin:一个好主意是不要这样做。给定
int32\u t i
,只需将字符
i&0xFF
(i/256)&0xFF
(i/65536)&0xFF
(i/16777216)&0xFF
@MSalters写入,为了更好的可读性,我将使用位移位而不是除法。特别是当我们将其扩展到
int64_t
;)
std::ifstream ifs("example.bin", std::ios::binary);

int i = 0;
ifs.read((char*) (&i), sizeof(i));

ifs.close();
#include <cstdint>

...
int32_t i = 128;
ofs.write((char*)(&i), sizeof(i));
...
...
int i = 128;
static_assert(sizeof(i) == 4, "Field i has to have size 4.");
ofs.write((char*)(&i), sizeof(i));
...
include <stdint.h>