2

在 C 程序中,我有一个 long* 想要序列化(从而转换为字符)。long 不适合单个字符,并且大小因处理器而异(可以是 4 字节或 8 字节)。

有什么好方法可以进行序列化和反序列化?

4

6 回答 6

3

这是可移植的,但远不如使用 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 编译器,所以我无法确认它是否适用于有符号整数。如果记忆对我有用,它的行为可能是未定义的(尽管我如何处理它可能并不重要)。

于 2008-10-07T22:28:46.573 回答
2

您可能正在解决错误的问题。您应该序列化为固定大小的 int,例如使用 int32_t。您可能希望在整个程序中使用这种固定大小的类型,否则当 64 位程序无法保存到较小的大小(或使用 int64_t)时,您会遇到问题。

如果知道您永远不必在 32 位平台上加载 64 位保存,那么请不要打扰。只需将 sizeof(long) 字节写入文件,然后读回 sizeof(long) 字节。但在数据的早期放置一个标志来指示源平台以避免错误。

于 2008-10-02T19:31:54.263 回答
2

您不必序列化为字符 - 您可以 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]);
}
于 2008-10-02T19:51:55.133 回答
1
long * longs;

// ...

int numChars = numLongs * sizeof(long);
char* longsAsChars = (char*) longs;
char* chars = malloc(numChars);
memcpy(chars, longsAsChars, numChars);
于 2008-10-02T19:26:44.367 回答
1

在 C 中,您可以获得 long 的大小

sizeof(long)

但是,如果您存储的 long 必须可以在多个平台之间传输,您应该始终将其序列化为 4​​ 个字节。无论如何,4byte 处理器无法读取更大的数字。

于 2008-10-02T19:29:47.620 回答
0

如果您创建一个指向长数组开头的 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"
}
于 2008-10-02T19:26:28.393 回答