原地址:http://blog.csdn.net/foruok/article/details/17715969

在一个跨平台( Android 、Windows、Linux )项目中配置文件用 INI 格式,自己写了个解析库,纯C语言的,简单好用。

可以解析 INI 格式的字符串、解析文件、保存到文件。

下面是头文件:

  1. #ifndef INI_PARSER_H
  2. #define INI_PARSER_H
  3. #ifdef __cplusplus
  4. extern "C" {
  5. #endif
  6. struct tag_value_list;
  7. struct ini_parser {
  8. struct tag_value_list * keyvalues;
  9. int (*parse_file)(struct ini_parser *, const char * file);
  10. int (*parse_string)(struct ini_parser *, const char *text);
  11. char * (*value)(struct ini_parser *, const char * key);
  12. void (*set_value)(struct ini_parser *, const char * key, const char * value);
  13. void (*remove)(struct ini_parser *, const char *key);
  14. int (*save_to_file)(struct ini_parser *, const char * file);
  15. };
  16. struct ini_parser * new_ini_parser();
  17. void delete_ini_parser(struct ini_parser *);
  18. #ifdef __cplusplus
  19. }
  20. #endif
  21. #endif // INI_PARSER_H

下面是源文件:

  1. #include "ini_parser.h"
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include "tag_value.h"
  5. static struct tag_value_pair * parse_line(char *line, int len)
  6. {
  7. struct tag_value_pair * pair = 0;
  8. int count = 0;
  9. char * p = line;
  10. char * end = 0;
  11. char * start = line;
  12. if(!p) return 0;
  13. while(*p == ' ') p++;
  14. /*blank line*/
  15. if(p - line == len ||
  16. *p == '\r' ||
  17. *p == '\n' ||
  18. *p == '\0') return 0;
  19. /*do not support group*/
  20. if(*p == '[') return 0;
  21. /*comments*/
  22. if(*p == '#') return 0;
  23. /* extract key */
  24. start = p;
  25. end = line + len;
  26. while(*p != '=' && p!= end) p++;
  27. if(p == end)
  28. {
  29. /* none '=' , invalid line */
  30. return 0;
  31. }
  32. end = p - 1;
  33. while(*end == ' ') end--; /* skip blank at the end */
  34. count = end - start + 1;
  35. pair = new_tag_value_pair();
  36. pair->szTag = malloc(count + 1);
  37. strncpy(pair->szTag, start, count);
  38. pair->szTag[count] = 0;
  39. /* extract value */
  40. p++;
  41. end = line + len; /* next pos of the last char */
  42. while( *p == ' ' && p != end) p++;
  43. if(p == end)
  44. {
  45. delete_tag_value_pair(pair);
  46. return 0;
  47. }
  48. start = p;
  49. end--; /* to the last char */
  50. if(*end == '\n') { *end = 0; end--; }
  51. if(*end == '\r') { *end = 0; end--; }
  52. count = end - start + 1;
  53. if(count > 0)
  54. {
  55. pair->szValue = malloc(count + 1);
  56. strncpy(pair->szValue, start, count);
  57. pair->szValue[count] = 0;
  58. }
  59. /* release empty key-value pair */
  60. if(!pair->szValue)
  61. {
  62. delete_tag_value_pair(pair);
  63. return 0;
  64. }
  65. return pair;
  66. }
  67. static int _parse_file(struct ini_parser * ini, const char *file){
  68. FILE * fp = fopen(file, "r");
  69. if(fp)
  70. {
  71. struct tag_value_pair * pair = 0;
  72. char buf[1024] = {0};
  73. while(fgets(buf, 1024, fp))
  74. {
  75. pair = parse_line(buf, strlen(buf));
  76. if(pair)
  77. {
  78. ini->keyvalues->add(ini->keyvalues, pair);
  79. }
  80. }
  81. fclose(fp);
  82. return ini->keyvalues->size;
  83. }
  84. return -1;
  85. }
  86. static int _parse_text(struct ini_parser * ini, const char * text){
  87. char *p = text;
  88. char * start = 0;
  89. struct tag_value_pair * pair = 0;
  90. if(!text) return -1;
  91. while(1)
  92. {
  93. start = p;
  94. while(*p != '\n' && *p != '\0' )p++;
  95. if(*p == '\0') break;
  96. pair = parse_line(start, p - start);
  97. if(pair) ini->keyvalues->add(ini->keyvalues, pair);
  98. p++;
  99. }
  100. return ini->keyvalues->size;
  101. }
  102. static char * _value(struct ini_parser * ini, const char * key){
  103. struct tag_value_pair * pair = ini->keyvalues->find_by_tag(ini->keyvalues, key);
  104. if(pair) return pair->szValue;
  105. return 0;
  106. }
  107. static void _set_value(struct ini_parser * ini, const char * key, const char *value){
  108. struct tag_value_pair * pair = ini->keyvalues->find_by_tag(ini->keyvalues, key);
  109. if(pair)
  110. {
  111. if(pair->szValue) free(pair->szValue);
  112. pair->szValue = strdup(value);
  113. }
  114. else
  115. {
  116. ini->keyvalues->add(ini->keyvalues, make_tag_value_pair(key, value));
  117. }
  118. }
  119. static void _remove(struct ini_parser * ini, const char * key){
  120. struct tag_value_pair * pair = ini->keyvalues->find_by_tag(ini->keyvalues, key);
  121. if(pair)ini->keyvalues->remove(ini->keyvalues, pair);
  122. }
  123. static void write_keyvalue(struct tag_value_pair * pair, FILE *fp)
  124. {
  125. fputs(pair->szTag, fp);
  126. fputc('=', fp);
  127. fputs(pair->szValue, fp);
  128. fputc('\n', fp);
  129. }
  130. static int _save_to_file(struct ini_parser * ini, const char * file){
  131. if(ini->keyvalues->size > 0)
  132. {
  133. FILE * fp = fopen(file, "w");
  134. if(fp)
  135. {
  136. struct tag_value_pair * pair = ini->keyvalues->head;
  137. while(pair != ini->keyvalues->tail)
  138. {
  139. write_keyvalue(pair, fp);
  140. pair = pair->next;
  141. }
  142. if(pair)write_keyvalue(pair, fp);
  143. fclose(fp);
  144. return 0;
  145. }
  146. }
  147. return -1;
  148. }
  149. struct ini_parser * new_ini_parser(){
  150. struct ini_parser * ini = (struct ini_parser*)malloc(sizeof(struct ini_parser));
  151. ini->keyvalues = new_tag_value_list();
  152. ini->parse_file = _parse_file;
  153. ini->parse_string = _parse_text;
  154. ini->value = _value;
  155. ini->set_value = _set_value;
  156. ini->remove = _remove;
  157. ini->save_to_file = _save_to_file;
  158. return ini;
  159. }
  160. void delete_ini_parser(struct ini_parser *ini){
  161. if(ini)
  162. {
  163. delete_tag_value_list(ini->keyvalues);
  164. free(ini);
  165. }
  166. }

测试代码:

  1. #include "util/ini_parser.h"
  2. #include "ini_test.h"
  3. #include <stdio.h>
  4. #include <assert.h>
  5. static char * g_szIniString = "#abc\nfirst=2\nsecond\nname=charli  zhang \n";
  6. static void ini_parser_test_string()
  7. {
  8. struct ini_parser * ini = new_ini_parser();
  9. int size = ini->parse_string(ini, g_szIniString);
  10. assert( size > 0);
  11. assert( ini->value(ini, "second") == 0 );
  12. assert( ini->value(ini, "abc") == 0);
  13. assert( ini->value(ini, "name") != NULL );
  14. assert( ini->value(ini, "first") != NULL);
  15. printf("ini string: %s\n", g_szIniString);
  16. printf("key-value pairs count = %d\n", size);
  17. printf("key \'name\'', value = %s\n", ini->value(ini, "name"));
  18. printf("key \'first\'', value = %s\n", ini->value(ini, "first"));
  19. ini->set_value(ini, "baidu", "hahaha");
  20. ini->save_to_file(ini, "write.conf");
  21. ini->remove(ini, "first");
  22. ini->save_to_file(ini, "write2.conf");
  23. delete_ini_parser(ini);
  24. }
  25. static void ini_parser_test_file()
  26. {
  27. struct ini_parser * ini = new_ini_parser();
  28. int size = ini->parse_file(ini, "test.conf");
  29. assert( size > 0);
  30. assert( ini->value(ini, "second") == 0 );
  31. assert( ini->value(ini, "abc") == 0);
  32. assert( ini->value(ini, "name") != NULL );
  33. assert( ini->value(ini, "first") != NULL);
  34. printf("ini string: %s\n", g_szIniString);
  35. printf("key-value pairs count = %d\n", size);
  36. printf("key \'name\'', value = %s\n", ini->value(ini, "name"));
  37. printf("key \'first\'', value = %s\n", ini->value(ini, "first"));
  38. printf("key \'baidu\'', value = %s\n", ini->value(ini, "baidu"));
  39. delete_ini_parser(ini);
  40. }
  41. void ini_parser_test()
  42. {
  43. ini_parser_test_string();
  44. ini_parser_test_file();
  45. }

测试了解析字符串、文件、增、删、写文件,都没什么大问题。

纯C语言INI文件解析的更多相关文章

  1. ini文件解析c库(iniparser)

    一.交叉编译ini解析库 1.官方网站http://ndevilla.free.fr/iniparser 下载iniparser-3.1.tar.gz 2.解压 tar -zxvf iniparser ...

  2. ini文件解析c库(iniparser)【转】

    转自:http://www.cnblogs.com/dyllove98/archive/2013/07/28/3221732.html 一.交叉编译ini解析库 .官方网站http://ndevill ...

  3. 超赞的 Go 语言 INI 文件操作

    灵活的数据源 不光光可以从文件读取配置,还支持 []byte 类型的纯数据读取和基于 io.ReadCloser 的流式读取. 多种格式兼容 各种文件种类的广泛支持,包括但不限于 my.cnf..gi ...

  4. C++——INI文件详解

    原创声明:本文系博主原创文章,转载及引用请注明出处. 1. INI文件介绍 INI是英文单词 INItialization 的缩写,常作为Windows系统下的配置文件.INI文件是文本文件,通常用于 ...

  5. boost::property_tree读取解析ini文件--推荐

    boost::property_tree读取解析ini文件 #include "stdafx.h" #include <iostream> #include <b ...

  6. 实战parse_ini_file()及扩展函数解析ini文件完整版

    文章来源:PHP开发学习门户 地址:http://www.phpthinking.com/archives/587 在PHP站点开发的过程中,往往会用到读取ini參数配置文件,比方须要訪问一些复杂的借 ...

  7. python解析ini文件

    python解析ini文件 使用configparser - Configuration file parser sections() add_section(section) has_section ...

  8. 解决ini-parser解析ini文件中文乱码问题

    rickyah/ini-parser 是一个.net 平台解析ini文件的库,当ini文件中含有中文字符时会乱码. 解决:将文件通过Editplus 等文本编辑工具保存为 utf-8 + bom 格式 ...

  9. 【WPS】表格使用VBA宏编程写入ini文件实现软件多语言

    前言:公司软件最近在做多语言版本,而又来一个西班牙文版本的,之前已经做过中文版本,英文版本和法文版本,之前是同事做的,现在安排我做,之前的做法,使用wps表格,翻译好,然后一个一个复制粘贴到ini文件 ...

随机推荐

  1. spoj 1812 lcsII (后缀自动机)

    spoj 1812 lcsII (后缀自动机) 题意:求多个串的lcs,最多10个串,每个串最长10w 解题思路:后缀自动机.先建好第一个串的sam,然后后面的串拿上去跑(这个过程同前一题).sam上 ...

  2. android模拟器 一个错误:X Error of failed request: BadRequest (invalid request code or no such operation)

    最近ubuntu12.04学习python,python2.7 python3.2所不同的是还是蛮大的.学习思考的新 升级后 结果显示 输入方法不显示   update-manager 和  add- ...

  3. Android使用学习之画图(Canvas,Paint)与手势感应及其应用(乒乓球小游戏)

    作为一个没有学习Android的菜鸟,近期一直在工作之外努力地学习的Android的使用. 这周看了下Android的画图.主要是Canvas,Paint等,感觉须要实践下.下午正好有空,就想整一个乒 ...

  4. BZOJ 1529: [POI2005]ska Piggy banks( 并查集 )

    每一连通块砸开一个就可以拿到所有的钱, 所以用并查集求连通块数 ------------------------------------------------------------------- ...

  5. perl use utf8

    utf8 Perl编译 来启用/禁用 UTF-8(or UTF-EBCDIC) 在源代码里 简洁: use utf8; no utf8; # Convert the internal represen ...

  6. nest expression &amp; Pyparsing

    http://pyparsing.wikispaces.com/ http://bbs.csdn.net/topics/330052586 C++ boost "<([^<> ...

  7. Qt入门-字符串类QString

    原地址:http://blog.csdn.net/xgbing/article/details/7770854 QString是Unicode字符的集合,它是Qt API中使用的字符串类. QStri ...

  8. 原始的js代码和jquery对比

    Even a task as simple as this can be complicated without jQuery at our disposal. In plain JavaScript ...

  9. cookie的path和domain參数实例解析

    一句话概括两个參数含义各为: path表示cookie所在的文件夹 domain表示的是cookie所在的域,默觉得请求的地址 首先改动我们的 hosts 文件 我本机内网ip 192.168.1.1 ...

  10. JSP的学习(4)——中文乱码的解决

    本篇将以JSP页面中可能存在的中文乱码问题进行分析和解决. 中文乱码的问题一直是国人在编程过程中的一大头疼问题,这点上在JSP.Servlet或Tomcat上随处可见.比如我们在写一个Servlet时 ...