在 C 程序中,我有一个 long* 想要序列化(从而转换为字符)。long 不适合单个字符,并且大小因处理器而异(可以是 4 字节或 8 字节)。
有什么好方法可以进行序列化和反序列化?
在 C 程序中,我有一个 long* 想要序列化(从而转换为字符)。long 不适合单个字符,并且大小因处理器而异(可以是 4 字节或 8 字节)。
有什么好方法可以进行序列化和反序列化?
这是可移植的,但远不如使用 printf/scanf 效率低
void longtochar(char *buffer, unsigned long number) {
int i;
for (i=0; i<sizeof(long); i++) {
buffer[i] = number & 0xFF; // place bottom 8 bits in char
number = number >> 8; // shift down remaining bits
}
return; // the long is now stored in the first few (2,4,or 8) bytes of buffer
}
并再次打开包装(假设 long 大小相同)
long chartolong(char *buffer) {
long number = 0;
int i;
for (i=sizeof(long)-1; i>=0; i--) {
number = number << 8; // left shift bits in long already
number += buffer[i]; // add in bottom 8 bits
}
return number;
}
请注意 BIG 假设,即 long 在两个系统上的长度相同。安全的做法是#include <stdint.h> 并使用它提供的类型(uint32_t 或 uint16_t)。
此外,我的代码将其作为无符号长。我现在无法访问 C 编译器,所以我无法确认它是否适用于有符号整数。如果记忆对我有用,它的行为可能是未定义的(尽管我如何处理它可能并不重要)。
您可能正在解决错误的问题。您应该序列化为固定大小的 int,例如使用 int32_t。您可能希望在整个程序中使用这种固定大小的类型,否则当 64 位程序无法保存到较小的大小(或使用 int64_t)时,您会遇到问题。
如果知道您永远不必在 32 位平台上加载 64 位保存,那么请不要打扰。只需将 sizeof(long) 字节写入文件,然后读回 sizeof(long) 字节。但在数据的早期放置一个标志来指示源平台以避免错误。
您不必序列化为字符 - 您可以 fwrite as longs(到文件)。要序列化为 char 数组,请在开头输入一个字节以指示 int 的大小和字节顺序 - 您稍后将需要它。
IE
char *p = &long_array[0];
要以 char 的形式访问长数组,只需将其转换 - 并将数组的长度乘以 sizeof(long) 即可获得 chars 的大小。
一个简单的例子说明了这一点:
#include <stdio.h>
main()
{
int aaa[10];
int i;
char *p;
for(i=0;i<sizeof(aaa)/sizeof(aaa[0]);i++)
{
aaa[i] = i;
printf ("setting aaa[%d] = %8x\n",i,aaa[i]);
}
aaa[9] = 0xaabbccdd;
printf ("sizeof aaa (bytes) :%d\n",sizeof(aaa));
printf ("each element of aaa bytes :%d\n",sizeof(aaa[0]));
p = (char*) aaa;
for(i=0;i<sizeof(aaa);i++)
printf ("%d: %8x\n",i,(unsigned char)p[i]);
}
long * longs;
// ...
int numChars = numLongs * sizeof(long);
char* longsAsChars = (char*) longs;
char* chars = malloc(numChars);
memcpy(chars, longsAsChars, numChars);
在 C 中,您可以获得 long 的大小
sizeof(long)
但是,如果您存储的 long 必须可以在多个平台之间传输,您应该始终将其序列化为 4 个字节。无论如何,4byte 处理器无法读取更大的数字。
如果您创建一个指向长数组开头的 char 指针,当您通过 char“数组”递增时,您一次将获得 8 位。但是请注意,long 不会以 null 结尾(可能是),因此您需要跟踪它的结尾在哪里。
例如:
long list[MAX];
char *serial = list;
int chunk = sizeof(long);
int k;
for(k=0; k<(MAX*chunk); k++){
// do something with the "char"
}