3

如何使用 C 将结构“打包”和“写入”到文件中,以便:

结构一个{
    uint64_t 一个;
    字符* b;
    uint16_t c;
} 一种;
ab;
巴 = 3;
bb = "你好";
bc = 4;

写入文件为

00 00 00 00 00 00 00 03 48 65 6c 6c 6f 00 00 04
4

4 回答 4

9

在 C 中,您必须编写一个函数来为您执行此操作。您不能只将结构放到磁盘上,因为b没有支持字符串是没有意义的指针。而且,除非你知道(并且可以控制)你的编译器如何打包它的结构,否则你最好使用实用函数,即使没有指针。

而且,好像这还不够,您还应该输出字符串的长度,以便知道要读回多少字节。

你会寻找类似的东西:

int better_than_blat (FILE *f, struct a *x) {
    size_t len = strlen (x->b);
    if (fwrite (&(x->a), sizeof(long), 1, f) != 1) return -1;
    if (fwrite (&len, sizeof(size_t), 1, f) != 1) return -1;
    if (fwrite (x->b, len, 1, f) != 1) return -1;
    if (fwrite (&(x->c), sizeof(short), 1, f) != 1) return -1;
    return 0;
}

int better_than_unblat (FILE *f, struct a *x) {
    size_t len;
    if (fread (&(x->a), sizeof(long), 1, f) != 1) return -1;
    if (fread (&len, sizeof(size_t), 1, f) != 1) return -1;
    x->b = malloc (len + 1);
    if (x->b == NULL) return -1;
    memset (x->b, 0, len + 1);
    if (fread (x->b, len, 1, f) != 1) return -1;
    if (fread (&(x->c), sizeof(short), 1, f) != 1) return -1;
    return 0;
}
于 2010-08-11T08:55:19.007 回答
2

您必须编写自己的方式来序列化这些数据;编译器不会为您提供处理字符串的内置方法。那里有序列化库,但我不知道任何用于直接 C 的库。

但是,请考虑使用更结构化的方法来序列化数据,例如 json 或 xml。即使是 INI 文件也比原始二进制转储更好。原因如下:

  • 更容易调试
  • 更向前兼容
  • 不那么严格/容易出错
  • 如果您使用现有的图书馆,那么您将获得社区的回报。
  • 现有的库可能支持您稍后会摸不着头脑的功能,例如数组
  • 更好的跨平台兼容性。
于 2010-08-11T08:55:18.707 回答
0

以下会有帮助吗?

struct buffer {

  char bytes[1000];
  int nbytes;
};

struct buffer *new_buffer(){
  struct buffer b = (struct buffer*) malloc(sizeof(struct buffer));
  b->nbytes = 0;
  return b;
}

void append_long(struct buffer *b, long *l){
  memcpy(b->bytes + b->nbytes, l);
  b->nbytes += sizeof(*l);
}

// ...and so on for other types

void fwrite_buffer(FILE *fp, struct buffer *b){
  fwrite(b->bytes, sizeof(*b), 1, fp);
}

用法:

struct buffer *buf = new_buffer();
struct a b;
b.a = 3;
b.b = "Hello";
b.c = 4;
append_long(buf, &(b.a));
append_pointer(buf, &(b.b));
append_short(buf, &(b.b));
fwrite_buffer(fp, buf);
于 2010-08-11T08:59:28.980 回答
0

您可以安全地将结构打包到字节数组中,如果您不会在其中使用指针并将显式定义打包对齐方式。

例如(gcc):

结构一个{
    长一个;
    字符 b[256];
    短 c;
} __attribute__((__packed__));

int 大小 = sizeof(a);
无效*缓冲区= malloc(大小);
memcpy(缓冲区, (void*)a, 大小);
于 2010-08-11T09:12:40.650 回答