仿udhcpd配置文件读取的一段代码

  前段时间看udhcpd的源代码,后来因为没直接应用,也就放弃了。网上有文章udhcpd详解(搜索一下有很多),其中在介绍udhcpd的配置相关代码时,有如下一句话,学习了这段代码后,以后用到需要读配置文件的地方可以直接使用。恰巧项目需要,就认真学习了下这段代码。不得不说,高人就是高人,写得代码简直是艺术品。我再做任何改动都毁了这件艺术品。我参看的源代码是udhcp-0.9.8。主要文件看的文件就是file.c,相关头文件就是file.h和dhcp.h。下面我贴我应用的代码,建议直接看源代码,我做一点注释。

  下面是.c文件。

  1 struct general_config_t g_general_config;
  2 
  3 static struct config_keyword keywords[] = {
  4     /* keyword[14]    handler   variable address        default[30] */
  5     {"server_ip",    read_str,  &(g_general_config.server_ip),    "192.168.1.50"},
  6     {"my_id",        read_str,  &(g_general_config.my_id),    "lt1000"},
  7     {"position",read_str,&(g_general_config.my_positon),"not set position"},
  8     {"",        NULL,       NULL,                ""},
  9 };
 10 
 11 /***********************************************************************************************
 12 *函数名 :read_str
 13 *函数功能描述:关键字对应的参数为字符串
 14 *函数参数 : 输入参数字符串,存储输入参数的地址
 15 *函数返回值 : 1 成功返回1
 16 *作者 : nelson
 17 *函数创建日期 : 2015.12.09
 18 *函数修改日期 : 尚未修改
 19 *修改人 :尚未修改
 20 *修改原因 :  尚未修改
 21 *版本 : 1.0
 22 *历史版本 : 无
 23 ***********************************************************************************************/
 24 int read_str(char *line, void *arg)
 25 {
 26     char *dest = (char *)arg;   //arg是指向数组首地址的地址
 27 
 28     strcpy(dest,line);
 29 
 30     return 1;
 31 }
 32 
 33 /***********************************************************************************************
 34 *函数名 :read_config
 35 *函数功能描述:读配置文件
 36 *函数参数 :file 配置文件文件名 相对路径或者绝对路径都可以
 37 *函数返回值 :成功返回1 失败返回0
 38 *作者 : nelson
 39 *函数创建日期 : 2015.12.09
 40 *函数修改日期 : 尚未修改
 41 *修改人 :尚未修改
 42 *修改原因 :  尚未修改
 43 *版本 : 1.0
 44 *历史版本 : 无
 45 ***********************************************************************************************/
 46 int read_config(char *file)
 47 {
 48     FILE *in;
 49     char buffer[80], *token, *line;
 50     int i;
 51 
 52     for (i = 0; strlen(keywords[i].keyword); i++)
 53     {
 54         if (strlen(keywords[i].def))
 55             keywords[i].handler(keywords[i].def, keywords[i].var);
 56     }
 57 
 58     if (!(in = fopen(file, "r")))
 59     {
 60         Important_Printf("config file not found,using the default value!");
 61         return 0;
 62     }
 63 
 64     while (fgets(buffer, 80, in))
 65     {
 66         if (strchr(buffer, '
'))
 67             *(strchr(buffer, '
')) = '';
 68 
 69         if (strchr(buffer, '#'))
 70             *(strchr(buffer, '#')) = '';
 71 
 72         token = buffer + strspn(buffer, " 	");
 73         if (*token == '')
 74             continue;
 75         line = token + strcspn(token, " 	=");
 76         if (*line == '')
 77             continue;
 78         *line = '';
 79         line++;
 80 
 81         /* eat leading whitespace */
 82         line = line + strspn(line, " 	=");
 83         /* eat trailing whitespace */
 84         for (i = strlen(line); i > 0 && isspace(line[i - 1]); i--);
 85         line[i] = '';
 86 
 87         for (i = 0; strlen(keywords[i].keyword); i++)
 88         {
 89             if(!strcmp(token, keywords[i].keyword))
 90             {
 91                 if (!keywords[i].handler(line, keywords[i].var))
 92                 {
 93                     keywords[i].handler(keywords[i].def, keywords[i].var);
 94                 }
 95             }
 96         }
 97     }
 98 
 99     fclose(in);
100 
101     return 1;
102 }
View Code

  然后是.h文件

 1 #define SERVER_IP_LEN 16
 2 #define MY_ID_LEN  12
 3 #define POSITION_STRING_LEN 30
 4 
 5 #pragma pack(1)
 6 struct config_keyword
 7 {
 8     char keyword[14];                            //关键字
 9     int (*handler)(char *line, void *var);       //关键字处理函数
10     void *var;                                   //关键字对应的输入参数存储地址
11     char def[30];                                //关键字对应的输入参数默认值
12 };
13 #pragma pack()
14 
15 #pragma pack(1)
16 struct general_config_t                          //全局配置参数结构体
17 {
18     char server_ip[SERVER_IP_LEN];                 /*save tcp server's ip*/
19     char my_id[MY_ID_LEN];                          /*id of myself*/
20     char my_positon[POSITION_STRING_LEN];          /*meachine's positon*/
21 };
22 #pragma pack()
23 
24 extern struct general_config_t g_general_config;
25 
26 int read_str(char *line, void *arg);
View Code

   稍微需要讲的是config_keyword结构体,不得不说设计的真好。

   然后就是strchr、strspn、strcspn、isspace这几个字符串操作函数。认真看,就会发现,使用strspn和strcspn可以从未知字符串中提取出自己想要的字符串,很方便。

原文地址:https://www.cnblogs.com/kanite/p/5038879.html