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

  下面是.c文件。

 struct general_config_t g_general_config;

 static struct config_keyword keywords[] = {
/* keyword[14] handler variable address default[30] */
{"server_ip", read_str, &(g_general_config.server_ip), "192.168.1.50"},
{"my_id", read_str, &(g_general_config.my_id), "lt1000"},
{"position",read_str,&(g_general_config.my_positon),"not set position"},
{"", NULL, NULL, ""},
}; /***********************************************************************************************
*函数名 :read_str
*函数功能描述:关键字对应的参数为字符串
*函数参数 : 输入参数字符串,存储输入参数的地址
*函数返回值 : 1 成功返回1
*作者 : nelson
*函数创建日期 : 2015.12.09
*函数修改日期 : 尚未修改
*修改人 :尚未修改
*修改原因 : 尚未修改
*版本 : 1.0
*历史版本 : 无
***********************************************************************************************/
int read_str(char *line, void *arg)
{
char *dest = (char *)arg; //arg是指向数组首地址的地址 strcpy(dest,line); return ;
} /***********************************************************************************************
*函数名 :read_config
*函数功能描述:读配置文件
*函数参数 :file 配置文件文件名 相对路径或者绝对路径都可以
*函数返回值 :成功返回1 失败返回0
*作者 : nelson
*函数创建日期 : 2015.12.09
*函数修改日期 : 尚未修改
*修改人 :尚未修改
*修改原因 : 尚未修改
*版本 : 1.0
*历史版本 : 无
***********************************************************************************************/
int read_config(char *file)
{
FILE *in;
char buffer[], *token, *line;
int i; for (i = ; strlen(keywords[i].keyword); i++)
{
if (strlen(keywords[i].def))
keywords[i].handler(keywords[i].def, keywords[i].var);
} if (!(in = fopen(file, "r")))
{
Important_Printf("config file not found,using the default value!");
return ;
} while (fgets(buffer, , in))
{
if (strchr(buffer, '\n'))
*(strchr(buffer, '\n')) = '\0'; if (strchr(buffer, '#'))
*(strchr(buffer, '#')) = '\0'; token = buffer + strspn(buffer, " \t");
if (*token == '\0')
continue;
line = token + strcspn(token, " \t=");
if (*line == '\0')
continue;
*line = '\0';
line++; /* eat leading whitespace */
line = line + strspn(line, " \t=");
/* eat trailing whitespace */
for (i = strlen(line); i > && isspace(line[i - ]); i--);
line[i] = '\0'; for (i = ; strlen(keywords[i].keyword); i++)
{
if(!strcmp(token, keywords[i].keyword))
{
if (!keywords[i].handler(line, keywords[i].var))
{
keywords[i].handler(keywords[i].def, keywords[i].var);
}
}
}
} fclose(in); return ;
}

  然后是.h文件

 #define SERVER_IP_LEN 16
#define MY_ID_LEN 12
#define POSITION_STRING_LEN 30 #pragma pack(1)
struct config_keyword
{
char keyword[]; //关键字
int (*handler)(char *line, void *var); //关键字处理函数
void *var; //关键字对应的输入参数存储地址
char def[]; //关键字对应的输入参数默认值
};
#pragma pack() #pragma pack(1)
struct general_config_t //全局配置参数结构体
{
char server_ip[SERVER_IP_LEN]; /*save tcp server's ip*/
char my_id[MY_ID_LEN]; /*id of myself*/
char my_positon[POSITION_STRING_LEN]; /*meachine's positon*/
};
#pragma pack() extern struct general_config_t g_general_config; int read_str(char *line, void *arg);

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

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

仿udhcpd配置文件读取的一段代码的更多相关文章

  1. vim移动一行或一段代码

    nmap <M-j> mz:m+<cr>`z nmap <M-k> mz:m-2<cr>`z vmap <M-j> :m'>+< ...

  2. 【Spring源码分析】配置文件读取流程

    前言 Spring配置文件读取流程本来是和http://www.cnblogs.com/xrq730/p/6285358.html一文放在一起的,这两天在看Spring自定义标签的时候,感觉对Spri ...

  3. Spring源码分析:Bean加载流程概览及配置文件读取

    很多朋友可能想看Spring源码,但是不知道应当如何入手去看,这个可以理解:Java开发者通常从事的都是Java Web的工作,对于程序员来说,一个Web项目用到Spring,只是配置一下配置文件而已 ...

  4. 使用VS Code开发.Net Core 2.0 MVC Web应用程序教程之三(配置文件读取)

    干了一天的活,还有点时间,给兄弟们写点东西吧. 大家有没有发现一个问题?那就是在.Net Core的MVC项目里面,没有.config文件了!!!同志们,没有config文件了啊,这样搞,我以后要做些 ...

  5. [spring源码学习]二、IOC源码——配置文件读取

    一.环境准备 对于学习源码来讲,拿到一大堆的代码,脑袋里肯定是嗡嗡的,所以从代码实例进行跟踪调试未尝不是一种好的办法,此处,我们准备了一个小例子: package com.zjl; public cl ...

  6. VS2012中,C# 配置文件读取 + C#多个工程共享共有变量 + 整理using语句

    (一) C# 配置文件读取 C#工程可以自动生成配置文件,以便整个工程可以使用设置的配置进行后续的处理工作. 1. 首先,右键工程文件-->Properties -->settings-- ...

  7. C 构造一个 简单配置文件读取库

    前言 最近看到这篇文章, json引擎性能对比报告 http://www.oschina.net/news/61942/cpp-json-compare?utm_source=tuicool 感觉技术 ...

  8. C# 配置文件读取与修改(转)

    C# 配置文件读取与修改   配置文件在很多情况下都使用到, 配置文件分为两种 一种是应用程序的配置文件, 一种是web的配置文件. 两种配置文件最大的区别是web的配置文件更新之后会实时更新, 应用 ...

  9. smarty 从配置文件读取变量

    smarty变量分3种: Variables [变量] Variables assigned from PHP [从PHP分配的变量] Variables loaded from config fil ...

随机推荐

  1. BZOJ 2438 [中山市选2011]杀人游戏 ——期望DP

    发现每一次死亡的几率相等,所以只需要判断最少问多少人即可. 并且环上的点任意询问都可以. 所以直接Tarjan缩点,然后计算入度为0的点的数目. 但是还有一些情况的时候会减少一次询问,比如说:$1-& ...

  2. BZOJ2654 tree 【二分 + 最小生成树】

    题目 给你一个无向带权连通图,每条边是黑色或白色.让你求一棵最小权的恰好有need条白色边的生成树. 题目保证有解. 输入格式 第一行V,E,need分别表示点数,边数和需要的白色边数. 接下来E行, ...

  3. 算法复习——费用流模板(poj2135)

    题目: Farm Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16898   Accepted: 6543 De ...

  4. Linux 下测试磁盘读写 I/O 速度的方法汇总

    在分布式异构存储系统中,我们经常会需要测量获取不同节点中硬盘/磁盘的读写 I/O 速度,下面是 Linux 系统下一些常用测试方法(之后不定期更新): 1.使用 hdparm 命令这是一个是用来获取A ...

  5. linux 中 stat 函数的用途和使用方法

    stat 函数讲解 表头文件:    #include <sys/stat.h> #include <unistd.h> 定义函数:    int stat(const cha ...

  6. 洛谷 [P2594] 染色游戏

    博弈论+SG函数的应用 这是一个二维翻硬币问题 一维翻硬币问题有一个结论: 局面的SG值等于局面中所有反面朝上的硬币单独存在时的SG值的异或和 这个结论同样适用于二维的翻硬币问题 证明可以用数学归纳法 ...

  7. hdu 4778 Gems Fight! 状压dp

    转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...

  8. python 之文件操作

    一.文件基本操作 1.文件的打开 打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作 文件句柄 = open('文件路径', '模式') 2. ...

  9. linux的at定时任务的使用

    linux的at定时任务的使用 使用at只能执行一次性任务:使用at命令需要开启atd进程. 以下情况需要安装at命令: 情况1.查看是否开启atd进程:ps -ef | grep atd.[test ...

  10. easyui分页时,总页数出错

    错误出现 MyBatis用easyui写后台分页代码时,出现翻页后显示总页数错误 代码如下 可能原因在于后台mappers.xml里的sql语句错误 <select id="getPr ...