C 实现二进制文件读写

  利用给出的数据结构:

typedef struct recv_data

 {  

      char    ip[32];

      short   port;               //socket port

      char    buff[PACKET_SIZE];

      short   data_size;

      void    *ptr;

      void    *elm;

         

 } PACKED recv_data_t;

PACKET_SIZE = 4096

1. 首先构造造一个binary文件;

2. 用lua脚本读取这个文件;

3. 解析这个文件。

  本文只涉及第一项任务。

  需要创建一个二进制文件(binary),并对构造的文件内容进行读写,将结构体成员信息数据都写入到二进制文件中并能识别它。

  步骤:1. 利用fopen()函数来打开一个并创建一个二进制文件。

     FILE *fp;      /*FILE 是变量类型,是C中用于文件的标准数结构;声明fp是指向FILE类型的指针*/

     fp = fopen ("wf.dat", "wb");         /*wb参数是只写打开或建立一个二进制文件,只允许写数据;fp是文件指针。*/

心路历程:起初,想利用fgets()函数来从stream所指的文件内读入字符并存到参数s所指的内存空间里,后来发现这样做不可行,会导致程序逻辑上错误,所以改用fwrite 

2. 为了程序的可扩展性,将数据结构修改如下:

typedef struct recv_data

{

uint32_t ip;

uint16_t port;

void *ptr;

 

uint16_t data_size;

char buff[4096];

 

}  recv_data_t;

  以前文件是定长的,现在修改为:buff 最大4096,具体长度由 data_size 确定,于是第一版的代码需要修改。

其中uint32_t表示:uint32_t  unsigned int

uint16_t表示:uint32_t  unsigned short

  在程序中uint32_t、uint16_t都不是标准库的类型,而是扩展数据类型,编译时候会出现未声明错误,需要加上头文件#include <stdint.h>才行

心路历程:(1)我的想法是用malloc函数给data_buff分配内存空间,数据大小由data_size确定,然后将值写入到文件中。那就要为其声明一个指针变量来实现,我定义了一个指针变量p不过这样做貌似画蛇添足。

2)于是我将结构体的成员变量ipbuff修改为*ip*buff,这样就分配了内存空间来将值存入到data.ip中。Buff要求大小是4096,就也用malloc函数分配那么大的内存来存放data_size的内容。

3)后来发现结构体成员变量ip应该是unsigned int的值,而不是指针,于是又把代码修改了下。

3. 由fopen()函数创建并打开二进制文件后,处理过程如下:

(1)使用memset()函数将为结构体分配的内存空间初始化。

(2)由于ip是unsigned int类型的,所以先用sizeof计算ip的大小,再用memcpy()函数将32位ip 地址复制到结构体成员data.ip中。

(3)为端口号赋值。

(4)计算data的大小,data中的内容应该是字符串,所以用strcpy()函数将data_size的内容复制到data.buff中。

(5)由于*ptr和*elm是记录别的数据用的,可以认为是一个KEY,先把他初始化为NULL。

4. 处理完后,利用fwrite()函数将结构体中的数据依次写入到创建的binary文件中。

5. 利用fread()函数,按序将写入binary文件中的数据读出来。

6. 使用winhex工具,验证生成的binary文件,确认其中内容是否与定义的结构一致。

 

源代码如下:

1 #include < stdio.h >
2 #include < stdlib.h >
3 #include < string .h >
4 #include < stdint.h >
5
6
7 typedef struct recv_data
8
9 {
10 uint32_t ip;
11
12 uint16_t port;
13
14 void * ptr;
15
16 uint16_t data_size;
17
18 char buff[ 4096 ];
19
20 } recv_data_t;
21
22
23 int main ( int argc, char ** argv)
24
25 {
26 FILE * fp;
27
28 recv_data_t data;
29
30 memset( & data, 0 , sizeof (data));
31 uint32_t ip = 3232261121u ; // 192.168.100.1的十进制表示
32 memcpy( & data.ip, & ip, sizeof (uint32_t));
33 data.port = 9876 ;
34 data.data_size = strlen( " text message, 1234567890! " );
35
36 strcpy(data.buff, " test message, 1234567890! " );
37
38 data.data_size = strlen(data.buff);
39
40 data.ptr = NULL;
41
42 fp = fopen ( " wf.dat " , " wb " );
43 if (fp == NULL)
44 {
45 printf ( " open file fail\n " );
46
47 return - 1 ;
48
49 }
50
51 fwrite ( & data.ip, sizeof (data.ip), 1 ,fp);
52 fwrite ( & (data.port), sizeof (data.port), 1 , fp);
53 fwrite ( & (data.data_size), sizeof (data.data_size), 1 , fp);
54 fwrite (data.buff, data.data_size, 1 , fp);
55
56 fclose(fp);
57
58 fp = fopen( " wf.dat " , " rb " );
59
60 fread ( & data.ip, sizeof (data.ip), 1 ,fp);
61 printf( " %u\n " ,data.ip);
62
63 fread ( & (data.port), sizeof (data.port), 1 ,fp);
64 printf( " %d\n " ,data.port);
65
66 fread ( & (data.data_size), sizeof (data.data_size), 1 ,fp);
67 printf( " %d\n " ,data.data_size);
68
69 fread (data.buff,data.data_size, 1 ,fp);
70 printf( " %s\n " ,data.buff);
71
72 fclose(fp);
73
74 return 0 ;
75
76 }

转载于:https://www.cnblogs.com/kevinji/archive/2011/06/23/2088500.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值