且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

"串行化" C中的结构

更新时间:2023-02-15 20:10:47

你好,


因为你不想要要写一个序列化函数,我建议将
编码(比如base64)将结构转换成字符串,然后将该字符串写入

文件。

对于阅读,你会读取字符串,解码它以使结构返回

再次。


如果你添加成员,你必须重写旧文件....除非你可以通过结构中的''version'字段来控制它...


-

Elias

" copx" <在***** @ invalid.com>在消息中写道

news:3f *********************** @ newsread4.arcor-online.net ...
Hello,

Since you don''t want to write a serialization function, I would suggest
encoding (say base64) the struct into a string then writing that string into
the file.
For reading you would read the string, decode it to get the struct back
again.

If you add members however, you have to rewrite old files....unless you can
control it via ''version'' field in your struct...

--
Elias
"copx" <in*****@invalid.com> wrote in message
news:3f***********************@newsread4.arcor-online.net...
我想将结构保存到磁盘....作为纯文本。
目前我使用的函数只使用fprintf写入数据。我的意思是这样的:
fprintf(fp,"%d%d",my_struct.a,my_struct.b)
这样我就要写另一个序列化
函数但是,我想要编写的每种新结构。是否有办法以便携方式编写可以以纯文本格式写入/读取任何结构的函数?

copx
I want to save a struct to disk.... as plain text.
At the moment I do it with a function that just
writes the data using fprintf. I mean like this:
fprintf(fp, "%d %d", my_struct.a, my_struct.b)
This way I have to write another "serializing"
function for every new kind of struct I want
to write, though. Is there a way to write
functions that can write/read any struct
to/from plain text format in a portable way?

copx



" copx" &LT;在***** @ invalid.com&GT;写道:
"copx" <in*****@invalid.com> writes:
我想将结构保存到磁盘....作为纯文本。
目前我用一个只用
写的函数来做使用fprintf的数据。我的意思是这样的:
fprintf(fp,"%d%d",my_struct.a,my_struct.b)
这样我就要写另一个序列化
函数但是,我想要编写的每种新结构。是否有办法以便携方式编写可以以纯文本格式写入/读取任何结构的函数?
I want to save a struct to disk.... as plain text.
At the moment I do it with a function that just
writes the data using fprintf. I mean like this:
fprintf(fp, "%d %d", my_struct.a, my_struct.b)
This way I have to write another "serializing"
function for every new kind of struct I want
to write, though. Is there a way to write
functions that can write/read any struct
to/from plain text format in a portable way?




这样的序列化函数需要知道每个结构成员的类型和位置

。如果您为每个

结构存储一次此信息,则可以将其作为附加参数传递给结构

序列化函数。下面的程序应该给你一些想法。


Martin


#include< stddef.h>

#include< stdio.h>


/ *将被序列化的结构。 * /

struct foo {

int a;

unsigned long b;

double c;

};


/ *有关结构成员的信息。 * /

struct member_info {

enum {NIL,TYPE_INT,TYPE_UINT,TYPE_LONG,TYPE_ULONG,TYPE_DOUBLE}类型;

size_t offset;

};


/ *有关struct foo成员的信息。 * /

const struct member_info foo_info [] = {

{TYPE_INT,offsetof(struct foo,a)},

{TYPE_ULONG,offsetof (struct foo,b)},

{TYPE_DOUBLE,offsetof(struct foo,c)},

{NIL,0}

} ;


void serialize(const void * const data,const struct member_info * info)

{

while(1)

{

开关(信息 - >类型)

{

案例TYPE_INT:

printf("%d",*(int *)((char *)data + info-> offset));

break;

case TYPE_UINT :

printf("%u",*(unsigned int *)((char *)data + info-> offset));

break;

case TYPE_LONG:

printf("%ld",*(long *)((char *)data + info-> offset));

休息;

案例TYPE_ULONG:

printf("%lu",*(unsigned long *)((char *)data + info-> offset ));

休息;

案例TYPE_DOUBLE:

printf("%f& quot;,*(double *)((char *)data + info-> offset));

break;

}


if((++ info) - > type == NIL)

{

putchar(''\ n'');

休息;

}

其他

putchar('''');

}

}


int main(无效)

{

struct foo myfoo = {42, 2004,3.1415926536};

serialize(& myfoo,foo_info);

返回0;

}



Such a serializing function would need to know the type and location
of each structure member. If you store this information once for every
structure, you can pass it as an additional argument to a structure
serializing function. The program below should give you some ideas.

Martin

#include <stddef.h>
#include <stdio.h>

/* Structure that will be serialized. */
struct foo {
int a;
unsigned long b;
double c;
};

/* Information about a structure member. */
struct member_info {
enum {NIL, TYPE_INT, TYPE_UINT, TYPE_LONG, TYPE_ULONG, TYPE_DOUBLE} type;
size_t offset;
};

/* Information about the members of struct foo. */
const struct member_info foo_info [] = {
{TYPE_INT, offsetof (struct foo, a)},
{TYPE_ULONG, offsetof (struct foo, b)},
{TYPE_DOUBLE, offsetof (struct foo, c)},
{NIL, 0}
};

void serialize (const void *const data, const struct member_info *info)
{
while (1)
{
switch (info->type)
{
case TYPE_INT:
printf ("%d", *(int *)((char *)data + info->offset));
break;
case TYPE_UINT:
printf ("%u", *(unsigned int *)((char *)data + info->offset));
break;
case TYPE_LONG:
printf ("%ld", *(long *)((char *)data + info->offset));
break;
case TYPE_ULONG:
printf ("%lu", *(unsigned long *)((char *)data + info->offset));
break;
case TYPE_DOUBLE:
printf ("%f", *(double *)((char *)data + info->offset));
break;
}

if ((++info)->type == NIL)
{
putchar (''\n'');
break;
}
else
putchar ('' '');
}
}

int main (void)
{
struct foo myfoo = {42, 2004, 3.1415926536};
serialize (&myfoo, foo_info);
return 0;
}


Martin Dickopp写道:
Martin Dickopp wrote:
" copx" &LT;在***** @ invalid.com&GT;写道:

"copx" <in*****@invalid.com> writes:

我想将结构保存到磁盘....作为纯文本。
目前我用一个只有使用fprintf写入数据。我的意思是这样的:
fprintf(fp,"%d%d",my_struct.a,my_struct.b)
这样我就要写另一个序列化
函数但是,我想要编写的每种新结构。是否有办法以便携方式编写可以以纯文本格式写入/读取任何结构的函数?
I want to save a struct to disk.... as plain text.
At the moment I do it with a function that just
writes the data using fprintf. I mean like this:
fprintf(fp, "%d %d", my_struct.a, my_struct.b)
This way I have to write another "serializing"
function for every new kind of struct I want
to write, though. Is there a way to write
functions that can write/read any struct
to/from plain text format in a portable way?



这样的序列化函数会需要知道每个结构成员的类型和位置。如果您为每个
结构存储一次此信息,则可以将其作为附加参数传递给结构序列化功能。下面的程序应该给你一些想法。

Martin


Such a serializing function would need to know the type and location
of each structure member. If you store this information once for every
structure, you can pass it as an additional argument to a structure
serializing function. The program below should give you some ideas.

Martin




两个评论:


( 1)虽然需要为每个结构成员编写代码

看起来像PITA,但这是一个很好的投资。相同的信息可用于

*其他*序列化功能,例如打印输出(考虑容易:

genericprintout(& myfoo,foo_info)et voila!),自动垃圾

收藏家,...


(2)如果结构中有指针,必须调用序列化器

递归地;这需要2个额外的簿记:

地址的表格,其结构已经被序列化,以避免重复
(一个使用标签代替);并且从结构的地址轻松访问信息表

(最简单的是始终有一个信息

指针作为每个结构的第一个字段)。 />

季节问候,

-

Michel Bardiaux

Peaktime Belgium SA Bd。 du Souverain,191 B-1160 Bruxelles

电话:+32 2 790.29.41



Two remarks:

(1) Although the need to write code for each and every structure member
can seem a PITA, it is a good investment. The same info can be used for
*other* serialization functions, such as printouts (consider the ease:
genericprintout(&myfoo, foo_info) et voila!), automatic garbage
collectors, ...

(2) If there are pointers in the structs, one must call the serializer
recursively; this requires 2 additional bookkeepings: a table of the
addresses of which structures have already been serialized, to avoid
duplications (one uses a tag instead); and easy access to the info table
from the address of a struct (the easiest is to have always an info
pointer as the first field of every struct).

Season greetings,
--
Michel Bardiaux
Peaktime Belgium S.A. Bd. du Souverain, 191 B-1160 Bruxelles
Tel : +32 2 790.29.41