C语言面向对象编程(六):配置文件解析

c语言读取xml配置文件 c语言读取xml配置文件 c语言要实现读取xml配置文件的功能。需要先编译libxml2库。 1、编译libxml2库 libxml2库从网络下载得到,这里下载的文件是:libxml2-sources-2.9.9.tar.gz 1.1、将libxml2文件拷贝到ubuntu系统下并解压 切换到libxml2库存在的路径下。 执行解压缩命令: tar -zxvf libxml2-sources-2.9.9.tar.gz 解压之后并切换到libxml2库路径下。 1.2、配置libxml2库 执行配置命 阅读详情

 在实际项目中,经常会把软件的某些选项写入配置文件。 Windows 平台上的 INI 文件格式简单易用,本篇文章利用《C语言面向对象编程(五):单链表实现》中实现的单链表,设计了一个“类” ini_parser 来读写 INI 格式的配置文件。

    struct ini_parser 可以解析 INI 格式的字符串、文件,也可以将内存中的符合 INI 格式的数据写入文件,能够支持 Windows 、 Linux 、 Android 等多平台。目前暂不支持选项分组功能。

    功能相对简单,直接看源码吧。

    下面是头文件:

 

 
  1. struct single_list;

  2.  
  3. struct ini_parser {

  4. struct single_list * keyvalues;

  5. int (*parse_file)(struct ini_parser *, const char * file);

  6. int (*parse_string)(struct ini_parser *, const char *text);

  7. char * (*value)(struct ini_parser *, const char * key);

  8. void (*set_value)(struct ini_parser *, const char * key, const char * value);

  9. void (*remove)(struct ini_parser *, const char *key);

  10. int (*save_to_file)(struct ini_parser *, const char * file);

  11. void (*deletor)(struct ini_parser *ini);

  12. };

  13.  
  14. struct ini_parser * new_ini_parser();

    struct init_parser 的声明符合我们在本系列文章中提到的面向对象框架,需要说明的是,一旦 deletor 方法被调用, ini_parser 的实例将不再允许访问。

 

    下面是源文件:

 

 
  1. #include "ini_parser.h"

  2. #include <stdio.h>

  3. #include <string.h>

  4.  
  5. struct tag_value_pair{

  6. struct slist_node node;

  7. char * szTag;

  8. char * szValue;

  9. };

  10. typedef struct tag_value_pair tag_value;

  11.  
  12. static void _tag_value_free(struct slist_node *node)

  13. {

  14. if(node) delete_tag_value_pair(node);

  15. }

  16.  
  17. static int _tag_value_hittest(struct slist_node * node, void *key)

  18. {

  19. return strcmp((char*)tag, ((struct tag_value_pair*)node)->szTag);

  20. }

  21.  
  22. static struct single_list * new_tag_value_list()

  23. {

  24. return new_single_list(_tag_value_free, _tag_value_hittest);

  25. }

  26.  
  27. static struct tag_value_pair *new_tag_value_pair()

  28. {

  29. struct tag_value_pair * pair = (struct tag_value_pair *)malloc(sizeof(struct tag_value_pair));

  30. pair->node.next = 0;

  31. pair->szTag = 0;

  32. pair->szValue = 0;

  33. return pair;

  34. }

  35.  
  36. static struct tag_value_pair * make_tag_value_pair(char * tag, char * value)

  37. {

  38. struct tag_value_pair *pair = 0;

  39. if(!tag || !value)return 0;

  40.  
  41. pair = (struct tag_value_pair*)malloc(sizeof(struct tag_value_pair));

  42. pair->szTag = strdup(tag);

  43. pair->szValue = strdup(value);

  44. pair->node.next = 0;

  45. return pair;

  46. }

  47.  
  48.  
  49. static struct tag_value_pair * parse_line(char *line, int len)

  50. {

  51. struct tag_value_pair * pair = 0;

  52. int count = 0;

  53. char * p = line;

  54. char * end = 0;m

  55. char * start = line;

  56. if(!p) return 0;

  57. while(*p == ' ') ++p;

  58.  
  59.  
  60. /*blank line*/

  61. if(p - line == len ||

  62. *p == '\r' ||

  63. *p == '\n' ||

  64. *p == '\0') return 0;

  65.  
  66. /*do not support group*/

  67. if(*p == '[') return 0;

  68. /*comments*/

  69. if(*p == '#') return 0;

  70.  
  71. /* extract key */

  72. start = p;

  73. end = line + len;

  74. while(*p != '=' && p!= end) ++p;

  75. if(p == end)

  76. {

  77. /* none '=' , invalid line */

  78. return 0;

  79. }

  80. end = p - 1;

  81. while(*end == ' ') --end; /* skip blank at the end */

  82. count = end - start + 1;

  83.  
  84. pair = new_tag_value_pair();

  85. pair->szTag = malloc(count + 1);

  86. strncpy(pair->szTag, start, count);

  87. pair->szTag[count] = 0;

  88.  
  89. /* extract value */

  90. ++p;

  91. end = line + len; /* next pos of the last char */

  92. while( *p == ' ' && p != end) ++p;

  93. if(p == end)

  94. {

  95. delete_tag_value_pair(pair);

  96. return 0;

  97. }

  98. start = p;

  99. --end; /* to the last char */

  100. if(*end == '\n') { *end = 0; --end; }

  101. if(*end == '\r') { *end = 0; --end; }

  102. count = end - start + 1;

  103. if(count > 0)

  104. {

  105. pair->szValue = malloc(count + 1);

  106. strncpy(pair->szValue, start, count);

  107. pair->szValue[count] = 0;

  108. }

  109.  
  110. /* release empty key-value pair */

  111. if(!pair->szValue)

  112. {

  113. delete_tag_value_pair(pair);

  114. return 0;

  115. }

  116.  
  117. return pair;

  118. }

  119.  
  120. static int _parse_file(struct ini_parser * ini, const char *file){

  121. FILE * fp = fopen(file, "r");

  122. if(fp)

  123. {

  124. struct tag_value_pair * pair = 0;

  125. char buf[1024] = {0};

  126. while(fgets(buf, 1024, fp))

  127. {

  128. pair = parse_line(buf, strlen(buf));

  129. if(pair)

  130. {

  131. ini->keyvalues->add(ini->keyvalues, pair);

  132. }

  133. }

  134. fclose(fp);

  135. return ini->keyvalues->size;

  136. }

  137. return -1;

  138. }

  139.  
  140. static int _parse_text(struct ini_parser * ini, const char * text){

  141. char *p = text;

  142. char * start = 0;

  143. struct tag_value_pair * pair = 0;

  144. if(!text) return -1;

  145.  
  146. while(1)

  147. {

  148. start = p;

  149. while(*p != '\n' && *p != '\0' )++p;

  150. if(*p == '\0') break;

  151.  
  152. pair = parse_line(start, p - start);

  153. if(pair) ini->keyvalues->add(ini->keyvalues, pair);

  154.  
  155. ++p;

  156. }

  157.  
  158. return ini->keyvalues->size;

  159. }

  160.  
  161. static char * _value(struct ini_parser * ini, const char * key){

  162. struct tag_value_pair * pair = NODE_T(ini->keyvalues->find_by_key(ini->keyvalues, key), struct tag_value_pair);

  163. if(pair) return pair->szValue;

  164. return 0;

  165. }

  166.  
  167. static void _set_value(struct ini_parser * ini, const char * key, const char *value){

  168. struct tag_value_pair * pair = NODE_T(ini->keyvalues->find_by_key(ini->keyvalues, key), struct tag_value_pair);

  169. if(pair)

  170. {

  171. if(pair->szValue) free(pair->szValue);

  172. pair->szValue = strdup(value);

  173. }

  174. else

  175. {

  176. ini->keyvalues->add(ini->keyvalues, make_tag_value_pair(key, value));

  177. }

  178. }

  179.  
  180. static void _remove(struct ini_parser * ini, const char * key){

  181. struct tag_value_pair * pair = NODE_T(ini->keyvalues->find_by_key(ini->keyvalues, key), struct tag_value_pair);

  182. if(pair)ini->keyvalues->remove(ini->keyvalues, pair);

  183. }

  184.  
  185. static void write_keyvalue(struct tag_value_pair * pair, FILE *fp)

  186. {

  187. fputs(pair->szTag, fp);

  188. fputc('=', fp);

  189. fputs(pair->szValue, fp);

  190. fputc('\n', fp);

  191. }

  192.  
  193. static int _save_to_file(struct ini_parser * ini, const char * file){

  194. if(ini->keyvalues->size > 0)

  195. {

  196. FILE * fp = fopen(file, "w");

  197. if(fp)

  198. {

  199. struct tag_value_pair * pair = NODE_T(ini->keyvalues->head,struct tag_value_pair);

  200. while(pair != 0)

  201. {

  202. write_keyvalue(pair, fp);

  203. pair = NODE_T(pair->node.next, struct tag_value_pair);

  204. }

  205.  
  206. fclose(fp);

  207. return 0;

  208. }

  209. }

  210. return -1;

  211. }

  212.  
  213. static void _delete_ini_parser(struct ini_parser *ini){

  214. if(ini)

  215. {

  216. ini->keyvalues->deletor(ini->keyvalues);

  217. free(ini);

  218. }

  219. }

  220.  
  221. struct ini_parser * new_ini_parser(){

  222. struct ini_parser * ini = (struct ini_parser*)malloc(sizeof(struct ini_parser));

  223. ini->keyvalues = new_tag_value_list();

  224. ini->parse_file = _parse_file;

  225. ini->parse_string = _parse_text;

  226. ini->value = _value;

  227. ini->set_value = _set_value;

  228. ini->remove = _remove;

  229. ini->save_to_file = _save_to_file;

  230. ini->deletor = _delete_ini_parser;

  231. return ini;

  232. }

    下面是简单的测试代码:

 
  1. static char * g_szIniString = "#abc\nfirst=2\nsecond\nname=charli zhang \n";

  2.  
  3. static void ini_parser_test_string()

  4. {

  5. struct ini_parser * ini = new_ini_parser();

  6. int size = ini->parse_string(ini, g_szIniString);

  7.  
  8. assert( size > 0);

  9. assert( ini->value(ini, "second") == 0 );

  10. assert( ini->value(ini, "abc") == 0);

  11. assert( ini->value(ini, "name") != NULL );

  12. assert( ini->value(ini, "first") != NULL);

  13.  
  14. printf("ini string: %s\n", g_szIniString);

  15. printf("key-value pairs count = %d\n", size);

  16. printf("key \'name\'', value = %s\n", ini->value(ini, "name"));

  17. printf("key \'first\'', value = %s\n", ini->value(ini, "first"));

  18.  
  19. ini->set_value(ini, "baidu", "hahaha");

  20. ini->save_to_file(ini, "write.conf");

  21.  
  22. ini->remove(ini, "first");

  23. ini->save_to_file(ini, "write2.conf");

  24.  
  25. ini->deletor(ini);

  26. }

  27.  
  28. static void ini_parser_test_file()

  29. {

  30. struct ini_parser * ini = new_ini_parser();

  31. int size = ini->parse_file(ini, "test.conf");

  32.  
  33. assert( size > 0);

  34. assert( ini->value(ini, "second") == 0 );

  35. assert( ini->value(ini, "abc") == 0);

  36. assert( ini->value(ini, "name") != NULL );

  37. assert( ini->value(ini, "first") != NULL);

  38.  
  39. printf("ini string: %s\n", g_szIniString);

  40. printf("key-value pairs count = %d\n", size);

  41. printf("key \'name\'', value = %s\n", ini->value(ini, "name"));

  42. printf("key \'first\'', value = %s\n", ini->value(ini, "first"));

  43. printf("key \'baidu\'', value = %s\n", ini->value(ini, "baidu"));

  44.  
  45. ini->deletor(ini);

  46. }

  47.  
  48. void ini_parser_test()

  49. {

  50. ini_parser_test_string();

  51. ini_parser_test_file();

  52. }

 

 

    struct ini_parser 已经运用在实际的项目中,目前为止没发现什么问题。

C语言读取写入 ini 配置文件 文章目录一、了解什么是INI文件?二、INI文件的格式三、解析上述文件四、测试如下 一、了解什么是INI文件? ini 文件是Initialization File的缩写,即初始化文件,这是用来配置应用软件以实现不同用户的要求。 二、INI文件的格式 INI文件由节、键、值组成。 一个简单的的INI文件例子如下: [Setting] INIT_FLAG=0; VOLUME=1; LANGUAGE=1; 如上例子,[Setting]就是节,=号左边的值是键,=号右边的是值。 三、解析上述文件 /*ini.h 阅读详情

相关推荐

linux c 解析配置文件

经常在程序中,我们需要从配置文件中读取变量值,配置文件可以是多种多样的格式,比如通用的xml文件或者自定义的配置文件。如果是xml配置文件,在解析的时候,我们需要借助第三方库,有的时候可能我们并不需要这样繁琐的获取配置文件变量的方式。所以更多时候可以通过自定义配置文件,然后自行解析。在实际编程过程中,我自己常用的定义配置文件的格式如下: my.conf [section_name_1] var

xiweiwei的专栏 2015

【C/C++】解析简单配置文件|解析从脚本读出的流配置

How to parse a simple config file 本文解释了如何解析类似于 Windows .ini 文件的 name=value 形式的配置文件。该代码从行中删除所有空格并跳过空行和包含注释的行。 配置文件的格式 The code explained in this article can parse both a formatted and unformatted input # formatted generates_output=true file_format=txt

我的笔记本 1297

C语言实战:从零开始编写一个通用配置文件解析器

本文介绍了如何通过C语言实现配置文件解析器,主要讲解了键值对格式的配置文件处理方法。文章首先定义了ConfigInfo结构体存储键值对,采用"两步解析法"读取文件:先统计有效行数确定内存大小,再解析填充数据。提供了trimSpace()处理字符串空格,isValidLine()判断有效行,以及getValueByKey()查询接口。最后通过hero.conf示例文件测试,展示了如何获取配置项的值。该方案具有格式清晰、内存管理严谨、接口简洁等特点,适用于各类配置文件的处理需求。

Web安全工具库 1444

C/C++ 读取配置文件的几种方式

介绍了使用protobuf、json、opencv、gflags 4种c/c++开发中常使用的加载配置文件的方法。

何高志 2325

c语言自定义配置文件解析

【代码】c语言自定义配置文件解析。

我不是码农的博客~~~ 239

C语言实现配置文件编写与解析完整指南

一个INI文件的典型结构如下所示:[database][logging]为了提升代码的可维护性和可扩展性,解析器应采用模块化设计。常见的模块包括文件读取模块、字符串处理模块和数据存储与接口封装模块。char* key;} Config;在C语言中,除了自研解析器,也有多个成熟的第三方配置解析库可以使用。下面我们介绍两个常用的库:libconfig和tinyconf。特性自研解析器libconfigtinyconf灵活性高(可定制)

weixin_42583683的博客 1191

C语言文件解析

简单介绍C语言文件操作,包括文件的打开关闭,读写。

qq_62319705的博客 2425

C语言 实现配置文件的编写与解析

C语言 实现配置文件的编写与解析

C语言面向对象编程之六:配置文件解析

在实际项目中,经常会把软件的某些选项写入配置文件。 Windows 平台上的 INI 文件格式简单易用,本篇文章利用《C语言面向对象编程之五:单链表实现》中实现的单链表,设计了一个“类” ini_parser 来读写 INI 格式的配置文件。     struct ini_parser 可以解析 INI 格式的字符串、文件,也可以将内存中的符合 INI 格式的数据写入文件,能够支持 Wi

CoolBreeze的博客 410

用C语言解析配置文件

用C语言实现解析配置文件的代码

无人机避障——Mid360+Fast-lio感知建图+Ego-planner运动规划(胎教级教程)

本工作将 Mid360 激光雷达、Fastlio-SLAM 和 Ego-Planner 集成,实现无人机的环境感知、定位建图和运动规划(仿真过程)—— 胎教级教程。

weixin_45390670的博客 1万+

c语言——配置文件读写

目录c语言——配置文件读写代码头文件主文件工具类判断当前行是否有效获得文件有效行数加载配置文件解析配置文件获得指定配置信息释放配置文件信息总的代码 c语言——配置文件读写 配置文件读写 文件的读取与关闭 在c++中调用c语言函数 二级指针作函数参数 三级指针作函数参数 二级指针赋值给三级指针 结构体二级指针 代码 头文件 ConfigFile.h #define _CRT_SECURE_NO_WARNINGS //防止头文件重复包含 #pragma once #include<stdio.h&g

mirana的专栏 7778

从隐式求解器到显式求解器:COMSOL接触仿真中的求解策略对比与选择

本文深度解析了COMSOL中隐式与显式求解器在接触仿真中的应用与选择策略。针对非线性接触问题的核心挑战,详细对比了两种求解器的数学框架、优化技术及适用场景,并提供了参数调优和调试技巧,帮助工程师高效解决接触仿真中的收敛问题。

weixin_28347369的博客 681

C语言如何解析配置文件?

一般服务器都是通过配置文件的解析获取关键的参数,不能够老是通过执行命令传进来,那么就有了配置文件,有了配置文件,就需要做配置文件的解析。 一般C语言格式配置文件的格式: #config.ini #the web is daemon or not daemon = yes #port set http=8000 https=4444 #default certifile ca= cert.pem #show dir or not dir= yes #dossl or not dossl=

一只青木呀 1774

科研作图不发愁:手把手教你用PyMOL给蛋白-DNA互作图‘美颜’(附完整配色与标注方案)

本文详细介绍了如何使用PyMOL对蛋白-DNA互作结构图进行专业美化,包括从PDB文件加载、结构展示与标注、互作位点突出显示到高质量渲染输出的完整流程。通过具体案例(PDB ID:8SSS)演示了锌指结构域区分、关键残基标注和互作距离测量等实用技巧,帮助科研人员制作可直接用于期刊投稿的高质量示意图。

weixin_42523792的博客 552

Android7以上抓取https数据包-无需root

手机内装一个虚拟机,然后在虚拟机内运行我需要抓包的应用,该虚拟机内是不需要证书验证的。完美解决android7.0以上https无法抓包的问题。

qq_45764684的博客 1454

C语言--面向对象编程之继承

系列文章目录 C语言实现面向对象编程的第二篇,在第一篇里面我们已经了解到了何为面向对象以及实现面向对象的第一大特性–封装,对于C来说,实现继承和多态要稍微麻烦一些。 C语言实现面向对象- - 封装 文章目录系列文章目录前言一、面向对象之继承何为继承?一个简单的Demo内存解析二、C++中继承内存分配demo代码简要分析三、总结 前言 这一篇将继续探讨用C实现面向对象编程之继承,用C来实现继承还是比较麻烦的,但是也能够实现继承,用C实现继承最好不要超过两级,不然实现继承与调用很繁琐。 一、面向对象之继承

weixin_46185705的博客 5191

流媒体协议-RTMP简介

与rtsp 不同,RTSP(Real-Time Streaming Protocol)是一个控制协议,负责控制媒体流的传输,但不传输媒体数据本身。RTSP 可以通过 TCP 或 UDP 传输 RTP 包来传输音视频数据。 RTMP(Real-Time Messaging Protocol)是一个综合性的协议,不仅可以传输音视频数据,还可以传输信令控制指令。RTMP 使用 TCP 作为传输协议,可以直接在 TCP 连接上传输音视频数据,也可以传输控制指令,实现了音视频流的实时传输和控制

xiaoshuaijinniu的博客 4550

Linux-配置文件ini解析实例——C语言

目录iniparser库作用及使用配置文件格式:ini配置文件实例ini文件解析实例 (aliyun_ini.c)iniparser库中的函数 iniparser库作用及使用 我们在Linux中做项目的时候一般都要用到配置文件,这样在源码中修改一些比如参数的时候我们就不用打开代码修改然后再重新编译,我们可以之间修改配置文件就行,我们项目发布出去之后用户也可以在看不到源码的情况下自己修改一些参数。 我写的配置文件主要是保存连接上阿里云所需要的认证信息,然后解析的话用的是iniparser库,这个库是C语言in

weixin_45506125的博客 2431

抖音直播间人气接口算法 抖音协议

抖音直播间人气接口算法 抖音协议 抖音算法

Q44804487的博客 1万+

sentaurus学习笔记(一)器件仿真

之前有跟大家说,以后转到sentaurus,因此silvaco会用的比较少,结果发现真的有一点贪心厌旧的感觉,现在基本上不用silvaco(lll¬ω¬)故这篇文章,将为大家带来的是关于sentaurus的结构仿真和器件的特性的提取。我们还是老规矩,先上结构图。 还是一个经典的IGBT结构,这是一个典型的N型IGBT,下面我将把一些相关的结构,和具体的写法用下面一幅图表达出来。 这里因为方便看,我们把器件的比例画的比较抽象。可以看到的是,这里有很多的距离参数是用一些变量名来写的,这也是sentaurus

weixin_43262021的博客 2万+

C语言的面向对象编程

面向对象编程(OOP)是一种通过封装、继承和多态等特性来组织代码的新方法。尽管C语言最初并不支持面向对象的思想,但通过一些技巧和约定,开发者可以在C语言中实现某种程度的面向对象编程。这篇文章将探讨C语言的面向对象编程的基本概念、实现方法和相关示例,并讨论其优缺点。

2501_90406542的博客 518

NX二次开发常用函数——从一个坐标系到另一个坐标系的转换(UF_MTX4_csys_to_csys )相同体坐标转化

本文介绍了在项目开发中实现坐标转换的方法,重点解析了两个关键函数UF_MTX4_csys_to_csys和UF_MTX4_vec3_multiply的使用。通过4个变换矩阵(transform1-4)实现工作坐标系与绝对坐标系之间的相互转换,并以圆柱体为例详细说明了坐标转换的具体实现过程,包括原点、X/Y轴方向的转换处理。相比之前采用的if-else判断方法,这种矩阵转换方式在代码复杂度和运行效率上都更具优势。

weixin_47753171的博客 599
上一篇: C语言面向对象编程(五):单链表实现
下一篇: new与malloc的区别以及实现方法
csshuke
博客等级 码龄16年 1517粉丝 8原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值