如何使用C将结构“打包”和“写入”到文件中,以便:
struct a { uint64_t a; char* b; uint16_t c; } a; a b; b.a = 3; b.b = "Hello"; b.c = 4;
以
的形式写入文件00 00 00 00 00 00 00 03 48 65 6c 6c 6f 00 00 04
答案 0 :(得分: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;
}
答案 1 :(得分:2)
你必须用自己的方式来序列化这些数据;编译器不会给你一个内置的方法来处理字符串。那里有序列化库,但我不知道直接C。
但是,请考虑使用更结构化的方法来序列化数据,例如json或xml。即使是INI文件也比原始二进制转储更好。原因是:
答案 2 :(得分: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);
答案 3 :(得分:0)
如果你不使用指针,你可以安全地将你的结构打包成字节数组,并明确定义打包对齐。
例如(gcc):
struct a { long a; char b[256]; short c; } __attribute__((__packed__)); int size = sizeof(a); void* buffer = malloc(size); memcpy(buffer, (void*)a, size);