我有一个cstring,源自gzread的调用。我知道数据是块,每个块都由unsigned int,char,int和unsigned short int组成。
所以我想知道将这个cstring拆分成适当变量的标准方法是什么。
说前4个字节,是unsigned int,下一个字节是char,接下来的4个字节是signed int,最后2个字节是unsigned short int。
//Some pseudocode below which would work
char buf[11];
unsigned int a;
char b;
int c;
unsigned short int d;
我想我可以用适当的补偿来记忆。
memcpy(&a, buf, sizeof(unsigned int));
memcpy(&b, buf+4, sizeof(char));
memcpy(&c, buf+5, sizeof(int));
memcpy(&d, buf+9, sizeof(unsigned short int));
或者使用一些比特操作员更好吗?就像转移和掩蔽一样。
或者将所有11个字节直接gz到某个结构中会更好,还是可能?是否修复了结构的内存布局,这是否适用于gzread?
答案 0 :(得分:2)
如果您打包结构(阅读__packed__
属性),您可以依赖订单并且成员不对齐。因此,您可以直接读入结构。但是,我不确定此解决方案的可移植性。
否则,使用指针魔术和类似的转换:
char *buffer;
int a = *(reinterpret_cast<int*> (buffer))
unsigned short b = *(reinterpret_cast<unsigned short*> (buffer + sizeof(int)))
答案 1 :(得分:2)
您需要确保文件的字节顺序与您运行代码的处理器体系结构相匹配。例如,如果整数写入文件中的最高有效字节,并且您的处理器使用最低有效字节优先顺序,那么您将获得结果垃圾。
如果要使代码从一个体系结构移植到另一个体系结构,则应根据目标处理器体系结构对宏管理字符顺序或整数管理字节顺序的整数进行所有读写操作。
答案 2 :(得分:1)
这取决于输入数据的定义方式。如果它被定义为以host-endian顺序(即,endianness总是与运行代码的系统匹配),那么你显示的memcpy()
是一个好的,可移植的方法。
或者,如果输入数据被定义为具有特定的字节序,那么最好的可移植解决方案是一次加载一个unsigned char
,使用shift和按位或。
答案 3 :(得分:1)
在您可以执行任何操作之前,您需要格式规范。是
它是文本或二进制文件(可能是您描述中的二进制文件,但只有一个
从来不知道)?用于签名值的表示形式是什么?什么
是字节顺序? memcpy
仅适用于您的计算机架构
完全对应于输入格式 - 今天罕见的情况,
因为几乎所有网络格式都是大端的,而且最普遍
架构是小端的。 (今天大多数格式和架构
使用2的补码表示负值,因此您可以经常“假设”
兼容性。但也有例外。)
鉴于此,数值重建的价值(使用掩蔽和 移位或乘法是唯一的便携式解决方案。根据 在机器和编译器的质量,它很容易导致 也有更好的表现。