我编写了一个程序,可以执行各种处理,并在文件中写入/读取结果。
这个“结果”在这样的结构中
struct res
{
char id;
char* values;
int count;
long samplenumber;
};
让我说我用这些函数写/读
write( file, &result, sizeof(struct res) );
read(file, &result, filesize(file) );
我担心的是:如果在32b机器上编写结构并在64位(以及其他方式)读取,可能会出现什么问题?
我不是要求对我目前正在做的事情进行任何改进,而是要考虑可移植性方面的问题。
答案 0 :(得分:4)
这里有4个问题:
〜类型的大小可以不同。 (使用来自stdint.h
的类型,例如uint32_t
。)
〜编译器通常会在你的结构中插入填充,比如
struct res
{
char id;
/* unused byte */
/* unused byte */
/* unused byte */
char* values;
int count;
long samplenumber;
};
〜整数的字节顺序可能不同。例如,3555896322
可以表示为
D3 F2 AC 02
或02 AC F2 D3
。
〜 char*
将作为无用指针保存到文件中。你需要自己逐字节地写字符串。
<强>解决方案:强>
〜使用stdint.h
中的类型。
〜不要使用结构进行保存。 (或者使用所谓的#pragma pack
,但请记住,它不可移植。)
〜逐字节写入整数,如
uint32_t var = 3555896322;
putc(var >> 0 & 0xff, file);
putc(var >> 8 & 0xff, file);
putc(var >> 16 & 0xff, file);
putc(var >> 24 & 0xff, file);
〜逐字节写字符串,例如:
const char *ptr = "Hello, young programmer!";
while (*ptr)
putc(*(ptr++), file);
putc('\0', file);
〜可以直接保存浮点类型,它们通常在任何地方都有相同的大小:
float a = 1.23;
fwrite(&a, sizeof (float), 1, file);
答案 1 :(得分:3)
根据我的经验,一切都会出错,因为平台上的类型大小不同。
首先使用stdint.h
#include <stdint.h>
struct res
{
uint8_t id;
char* values;
uint32_t count;
uint32_t samplenumber;
};
您也不应该将字符串写为char*
。当你再次阅读它时,你只会得到陈旧的指针。使用预定义大小的字符串:
char values[256];
或者在单独的写入调用中手动编写字符串。