带有位域和字符的 fwrite/fread 结构 *

Posted

技术标签:

【中文标题】带有位域和字符的 fwrite/fread 结构 *【英文标题】:fwrite/fread struct with bitfields and char * 【发布时间】:2018-03-12 18:54:06 【问题描述】:

我正在测试一个自定义结构,其中包含位域和无符号字符 *(稍后将分配)。

结构如下:

struct test 
  unsigned int field1 : 1;
  unsigned int field2 : 15;
  unsigned int field3 : 32;
  unsigned int dataLength : 16;
  unsigned char * data;
 

问题是当我尝试将此结构保存在十六进制文件中时。

例如:

int writeStruct(struct test *ptr, FILE *f) 

   // for data, suppose I know the length by dataLength  : 
   // this throw me : cannot take adress of bit field
   int count;
   count = fwrite( &(ptr->field2), sizeof(unsigned int), 1, f);

   // this throw me : makes pointer to integer without a cast
   count = fwrite( ptr->field2, sizeof(unsigned int), 1, f);

   // same for length
   count = fwrite( htons(ptr->data) , ptr->dataLength, 1,f);       

   // so , how to do that ?

同样的问题出现在 fread 上:

int readAnStructFromFile(struct test *ptr, FILE *f) 
   // probably wrong
   fread(ptr->field1, sizeof(unsigned int), 1, f);

那么,我怎样才能写/读这样的结构呢?

感谢您的帮助

PS for fread,如果没有这些位域,这可能会起作用:How to fread() structs?

【问题讨论】:

虽然为field1field2 使用位域似乎是有意义的,因为它们不是标准位宽,但对于field3dataLenght 来说意义不大,可以使用@分别为 987654329@ 和 uint16_t。而且,如果您不在内存受限的系统上,则通常根本不需要位域(然后将size_t 用于dataLength 成员),除非您尝试匹配其他一些数据结构(网络数据包,磁盘结构或类似结构)。 这是一个处理几种情况的例子:)。我尝试制作自定义网络数据包^^ 您真的需要以二进制格式存储文件吗?为什么不是json 之类的?由于使用fscanffprintf 的一致文件文本结构,这将更容易读回。 是的,它应该是二进制的,以便其他东西传输它.. 你明白shtons() 中的含义吗? 【参考方案1】:

没有办法获得位域的地址。处理它的常用方法是在读/写端使用临时变量,或者只是将整个结构保存为单个实体。使用临时变量,它如下所示:

int count;
int field2 = ptr->field2;
count = fwrite( &field2, sizeof(unsigned int), 1, f);
...
int field1;
fread(&field1, sizeof(unsigned int), 1, f);
ptr->field1 = field1;

或者对于整个结构:

count = fwrite( ptr, sizeof(struct test), 1, f);

【讨论】:

谢谢:我会测试你的第一个想法。你认为整个 struct fwrite 不会因为里面的指针而工作吗? 在您的情况下,整个结构写入将不起作用。它不会写入数据本身,只是没有意义的数据指针。 建议将其分成两部分:标题和数据。您可以作为一个整体编写的标题

以上是关于带有位域和字符的 fwrite/fread 结构 *的主要内容,如果未能解决你的问题,请参考以下文章

Linux 打开文件并写入一段字符串,同一时候读出相应文件的信息--fopen()/fwrite()/fread()

C 语言文件操作 ( fwrite 函数 )

fopen()fwrite()fread()函数使用说明与示例

编译器玄学研究报告第一期——位域和volatile

C 语言文件操作 ( fread 函数 )

open()fwrite()fread()函数使用说明与示例