自己写的,一个完整读取 ini 文件的库 ... ...

10阅读 0评论2025-07-03 snow888
分类:C/C++

为了写一个任务调度器,结果顺手做了一个消息中间件。
为了写一个消息中间件,结果顺手写了一个读取 ini 配置文件的类库。
虽然小,但是够用了。

rwini.c

点击(此处)折叠或打开

  1. #include <rwini.h>
  2. #include <zPublic.h>

  3. struct _inis *ini_loader(const char *inifile)
  4. {
  5.         FILE *fp;
  6.         int i,j,k;
  7.         static struct _inis inis[512];
  8.         char str[2048];
  9.         char str_remark[2048];
  10.         char str_key[2048];
  11.         char str_value[2048];
  12.         char str_desce[2048];

  13.         fp = fopen(inifile,"rb");
  14.         if ( fp == NULL )
  15.                 return NULL;

  16.         /* 从 ini 文件重读取信息,装入到 struct _inis 结构体 */
  17.         i = -1 ;
  18.         j = 0;
  19.         k = 0;
  20.         while(!feof(fp))
  21.         {
  22.                 bzero(str,2048);
  23.                 if ( fgets(str,2048,fp) == NULL )
  24.                         break;
  25.                 trim(str);
  26.                 if ( str[0] == '[' && str[strlen(str)-1] == ']' )
  27.                 {
  28.                         /* 是一个节点定义 */
  29.                         i++;
  30.                         if ( i > 0 )
  31.                         {
  32.                                 /* 不是首节点的时候 */
  33.                                 for(k = 0 ; k<j; k++ )
  34.                                         inis[i-1].ini_struct[k].max_key = j;
  35.                         }
  36.                         inis[i].node_name = (char *)malloc(sizeof(char)*strlen(str));
  37.                         if ( inis[i].node_name == NULL )
  38.                         {
  39.                                 fclose(fp);
  40.                                 return NULL;
  41.                         }
  42.                         j = 0 ;
  43.                         snprintf(inis[i].node_name,strlen(str)-1,"%s",str+1);
  44.                 } else {
  45.                         if ( str[0] == ';' || str[0] == '#' || str[0] == '\n' || str[0] == 0 || str == NULL)
  46.                         {
  47.                                 /* 首字符是 ; 号,抛弃 */
  48.                                 continue;
  49.                         }
  50.                         /* 不是一个节点,进行 key 和 value 拆解 */
  51.                         /* 获得注释信息 */
  52.                         bzero(str_remark,2048);
  53.                         snprintf(str_remark,2048,"%s",strstr(str,";")+1);
  54.                         inis[i].ini_struct[j].remark = ( char *) malloc(sizeof(char)*strlen(str_remark));
  55.                         bzero(inis[i].ini_struct[j].remark,strlen(str_remark));
  56.                         strcpy(inis[i].ini_struct[j].remark,str_remark);
  57.                         /* 得到剔除注释信息后的 key = value 的串 */
  58.                         bzero(str_desce,2048);
  59.                         snprintf(str_desce,strlen(str)-strlen(str_remark)+1,"%s",str);
  60.                         trim(str_desce);
  61.                         if ( str_desce[strlen(str_desce)-1] == ';' )
  62.                                 str_desce[strlen(str_desce)-1] = '\0';
  63.                         /* 获得 value 信息 */
  64.                         bzero(str_value,2048);
  65.                         snprintf(str_value,2048,"%s",strstr(str_desce,"=")+1);
  66.                         inis[i].ini_struct[j].value = ( char *) malloc(sizeof(char)*strlen(str_value));
  67.                         bzero(inis[i].ini_struct[j].value,strlen(str_value));
  68.                         strcpy(inis[i].ini_struct[j].value,str_value);
  69.                         trim(inis[i].ini_struct[j].value);
  70.                         /* 获得 key 信息 */
  71.                         bzero(str_key,2048);
  72.                         snprintf(str_key,strlen(str_desce)-strlen(str_value),"%s",str_desce);
  73.                         inis[i].ini_struct[j].key = ( char *) malloc(sizeof(char)*strlen(str_key));
  74.                         bzero(inis[i].ini_struct[j].key,strlen(str_key));
  75.                         strcpy(inis[i].ini_struct[j].key,str_key);
  76.                         trim(inis[i].ini_struct[j].key);
  77.                         j++;
  78.                 }
  79.         }
  80.         fclose(fp);
  81.         /* {BANNED}{BANNED}{BANNED}{BANNED}最佳佳佳佳后一个节点的 max_key 进行赋值 */
  82.         for(k = 0 ; k<j; k++ )
  83.                 inis[i].ini_struct[k].max_key = j;
  84.         /* 对inis 对象的 max_node 进行赋值 */
  85.         for ( k = 0 ; k <= i ; k++ )
  86.                 inis[k].max_node = i+1;
  87.         return inis;
  88. }


  89. /* ************************************************************************* *\
  90.  * 根据节点名称和key,查找对应的 value 值
  91.  * char *ini_search ( const struct _inis *inis,
  92.  * const char *nodename,
  93.  * const char *key,
  94.  * char **value)
  95.  * ************************************************************************* */
  96. char *ini_search ( const struct _inis *inis,const char *nodename,const char *key,char **value)
  97. {
  98.         int i,j;
  99.         for ( i = 0 ; i < inis[i].max_node ; i++ )
  100.         {
  101.                 if ( !strcmp(inis[i].node_name,nodename))
  102.                 {
  103.                         /* 找到了该节点 */
  104.                         for ( j = 0 ; j < inis[i].ini_struct[j].max_key; j++)
  105.                         {
  106.                                 if ( !strcmp(inis[i].ini_struct[j].key,key))
  107.                                 {
  108.                                         /* 找到了该节点对应的 key */
  109.                                         *value = inis[i].ini_struct[j].value;
  110.                                         return (inis[i].ini_struct[j].value);
  111.                                 }
  112.                         }
  113.                         return NULL;
  114.                 }
  115.         }
  116.         return NULL;
  117. }

  118. /* ***************************************************************************** *\
  119.  **iniPrt 中找的到指定节点并 dump 成一个单一的 iniPrt
  120.  * struct _inis ini_nodedump(const struct _inis *inis,
  121.  * const char *nodename)
  122.  * ****************************************************************************** */
  123. struct _inis ini_nodedump(const struct _inis *inis,const char *nodename)
  124. {
  125.         static struct _inis ss;
  126.         int i,j;
  127.         for ( i = 0 ; i < inis[i].max_node; i++ )
  128.         {
  129.                 if ( !strcmp(inis[i].node_name,nodename))
  130.                 {
  131.                         /* 找到了这个节点 */
  132.                         ss.node_name = (char *)malloc(sizeof(char)*strlen(inis[i].node_name));
  133.                         strcpy(ss.node_name , inis[i].node_name);
  134.                         for ( j = 0 ; j < inis[i].ini_struct[j].max_key; j++ )
  135.                         {
  136.                                 ss.ini_struct[j].key = (char *)malloc(sizeof(char)*strlen(inis[i].ini_struct[j].key));
  137.                                 strcpy(ss.ini_struct[j].key , inis[i].ini_struct[j].key);
  138.                                 ss.ini_struct[j].value = (char *)malloc(sizeof(char)*strlen(inis[i].ini_struct[j].value));
  139.                                 strcpy(ss.ini_struct[j].value , inis[i].ini_struct[j].value);
  140.                                 ss.ini_struct[j].max_key = inis[i].ini_struct[j].max_key;
  141.                         }
  142.                         break;
  143.                 }
  144.         }
  145.         return (ss);
  146. }

  147. #if 0
  148. int main ( int argc , char **argv )
  149. {
  150.         char *file;
  151.         //="test.ini";
  152.         int i,j;
  153.         char *value;

  154.         INI_Prt *ss;
  155.         INI_Prt st;

  156.         file = ( char *)malloc(sizeof(char)*128);
  157.         if ( argc < 2 )
  158.                 snprintf(file,128,"%s","test.ini");
  159.         else
  160.                 snprintf(file,128,"%s/conf/zSync.ini",getenv("HOME"));

  161.         /* 将 ini 文件加载到结构体 INI_Prt 指针 *ss */
  162.         if ( (ss = ini_loader(file)) == NULL)
  163.                 return 0;

  164.         /* 循环展示整个 ini 文件的 nodename . 每个 nodename 下对应的配置信息 */
  165.         for ( i = 0 ; i <= ss[i].max_node ; i++)
  166.         {
  167.                 printf("=== nodename = %s ==\n",ss[i].node_name);
  168.                 printf("=== max_node = %d ==\n",ss[i].max_node);
  169.                 for ( j = 0 ; j < ss[i].ini_struct[j].max_key ; j++)
  170.                 {
  171.                         printf("=== [%s].[%d].key = %s ==\n",ss[i].node_name,j,ss[i].ini_struct[j].key);
  172.                         printf("=== [%s].[%d].value = %s ==\n",ss[i].node_name,j,ss[i].ini_struct[j].value);
  173.                 }
  174.         }


  175.         /* 验证按照给定的节点名称,key 名,在 INI_Prt 指针中获取到对应的 value */
  176.         printf(" == %s ==\n",ini_search ( ss,"odbc","driver",&value));
  177.         printf(" 1== %s ==\n",value);

  178.         /* 验证从 INI_Prt *ss 中按照指定的 nodename 名,将该节点 dump 出来,形成一个新的 INI_Prt */
  179.         st = ini_nodedump(ss,"odbc");
  180.         for ( j = 0 ; j < st.ini_struct[j].max_key; j++ )
  181.         {
  182.                 printf(" == key = [ %s ] ==\n",st.ini_struct[j].key);
  183.                 printf(" == value = [ %s ] ==\n",st.ini_struct[j].value);
  184.         }

  185.         return 0;
  186. }
  187. #endif /* if 0 */

rwini.h

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <strings.h>

  5. #ifndef __RW_INI__
  6. #define __RW_INI__
  7. typedef struct _ini_p {
  8.         char *key;
  9.         char *value;
  10.         char *remark;
  11.         int max_key;
  12. }INI_Prt_Doc;


  13. typedef struct _inis {
  14.         char *node_name;
  15.         struct _ini_p ini_struct[512];
  16.         int max_node;
  17. }INI_Prt;


  18. struct _inis *ini_loader(const char *inifile);
  19. char *ini_search(const struct _inis *inis,const char *nodename,const char *key,char **value);
  20. struct _inis ini_nodedump(const struct _inis *inis,const char *nodename);


  21. #endif /* __RW_INI__ */

zPublic.h

点击(此处)折叠或打开

  1. #include <stdarg.h>
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <unistd.h>
  6. #include <signal.h>
  7. #include <sys/stat.h>
  8. #include <sys/param.h>
  9. #include <time.h>

  10. #ifndef __ZPUBLIC__
  11. #define __ZPUBLIC__

  12. #ifndef TRUE
  13. #define TRUE 1
  14. #endif

  15. #ifndef FALSE
  16. #define FALSE 0
  17. #endif

  18. #ifndef ERROR
  19. #define ERROR -1
  20. #endif

  21. #ifndef SUCCESS
  22. #define SUCCESS 1
  23. #endif

  24. #ifndef OK
  25. #define OK 0
  26. #endif





  27. #ifndef SPACE
  28. #define SPACE '\040'
  29. #endif

  30. #ifndef LF
  31. #define LF '\012'
  32. #endif

  33. #ifndef ESC
  34. #define ESC '\033'
  35. #endif

  36. #ifndef LOGFILE
  37. #define LOGFILE logfilename("zProgCTL-app")
  38. #endif



  39. #ifndef __THISFILE__
  40. #define __THISFILE__ basename(__FILE__)
  41. #endif

  42. #ifndef __FUNCTION__
  43. #define __FUNCTION__ (__func__)
  44. #endif

  45. #ifndef __FUNC__
  46. #define __FUNC__ (__func__)
  47. #endif

  48. #ifndef __MIN__
  49. #define __MIN__(a,b)( (a)<(b)?(a):(b) )
  50. #endif

  51. #ifndef __MAX__
  52. #define __MAX__(a,b)( (a)>(b)>(a):(b) )
  53. #endif

  54. #ifndef PATH_MAX
  55. #ifndef _POSIX_PATH_MAX
  56. #define PATH_MAX 1024
  57. #else
  58. #define PATH_MAX _POSIX_PATH_MAX
  59. #endif
  60. #endif


  61. #ifndef __LINE_MAX__
  62. #define __LINE_MAX__ 512
  63. #endif


  64. typedef struct _sec_link_node { /* ini 文件的节点 key - value 结构体,以双链表的方式实现 */
  65.         char node_key[80]; /* 节点中 key 的名称 */
  66.         char node_value[256]; /* 节点中 value 的值 */
  67.         struct _sec_link_node *next;
  68.         struct _sec_link_node *proi;
  69. } _SEC_LINK_NODE ;




  70. /* ******************************************************************* *
  71.  * return filename from logfilename function with const char * *
  72.  * *
  73.  * date : 2008-04-26 *
  74.  * ******************************************************************* */
  75. char *logfilename(const char *);

  76. int isValidTime(const char *,const char *); /* 判断字符串是否是时间格式 */
  77. int isValidNum(const char *); /* 判断字符串是否是数字 */
  78. char *getlogfilename(const char *s);
  79. int writelogfile(const char *,const char *, ...); /* 将信息写入日志文件 */
  80. int rtrim(char *str); /* 去掉字符串右边的空格 */
  81. int ltrim(char *str); /* 去掉字符串左边的空格 */
  82. int trim(char *str); /* 去掉字符串左右的空格 */
  83. int freadcnf_to_text ( const char *filename,char **text); /* 读取配置信息到内存 text[512][512]*/
  84. //int LoadIniFile(char *inifilename,const char *nodename , struct _Section *sec_ini);
  85. //char *get_sec_key_value( struct _Section *sec_ini , const char *key);
  86. _SEC_LINK_NODE *Init_Sec_Info(_SEC_LINK_NODE *sec_info); /* 初始化 ini 节点双链表 */
  87. _SEC_LINK_NODE *Install_Sec_Info(_SEC_LINK_NODE *sec_info,char *key,char *value,int addnum);
  88.                                                                 /* 插入配置文件 ini 某个节点的所有 key->value 到链表 */
  89. char *Select_Sec_Node (const char *filename,const char *sec_name,const char *key);
  90.                                                                 /* 从配置文件中读取指定节点的制定 key 的 value 值 */
  91. int checkFileExists(char *filename); /* 检查文件状态,文件是否存在 */
  92. void sha256(const unsigned char *data, size_t len, unsigned char *out);
  93.                                                                 /* 生成 sha256 字符串码 */
  94. void replace_str(char *str,const char *s1,const char *s2); /* 从字符串 str 中查找到所有的 s1 字符串内容,并用 s2 进行替换 */
  95. //void generate_uuid(char *uuid_str); /* 生成 uuid 字符串 */

  96. char *generate_date(char *date_str);
  97. char *generate_time(char *time_str);

  98. char *GetSystemTime();

  99. #endif /* __ZPUBLIC__ */

trim.c

点击(此处)折叠或打开

  1. #include <zPublic.h>
  2. /* TRIM LEFT */

  3. int rtrim( char *pszString)
  4. {
  5.         int nForwardCursor = 0;
  6.         int nTrailingCursor = 0;
  7.         int bTrim = 1;

  8.         for( nForwardCursor = 0 ; pszString[nForwardCursor] != '\0'; nForwardCursor++ )
  9.                 if ( bTrim && isspace( pszString[nForwardCursor] ))
  10.                         continue ;
  11.                 else {
  12.                         bTrim = 0;
  13.                         pszString[nTrailingCursor] = pszString[nForwardCursor];
  14.                         nTrailingCursor++;
  15.                 }
  16.         pszString[nTrailingCursor] = '\0';
  17.         return SUCCESS;
  18. }

  19. /* TRIM RIGHT */
  20. int ltrim( char *pszString )
  21. {
  22.         int nForwardCursor = 0;
  23.         int nTrailingCursor = 0;
  24.         int bTrim = 1;
  25.         for ( nForwardCursor=strlen(pszString)-1;
  26.                         nForwardCursor >= 0 && isspace( pszString[nForwardCursor] );
  27.                         nForwardCursor-- )
  28.         {
  29.         }
  30.         pszString[nForwardCursor+1] = '\0';
  31.         return SUCCESS;
  32. }

  33. /* TRIM LEFT & RIGHT */
  34. int trim(char *str)
  35. {
  36.         ltrim(str);
  37.         rtrim(str);
  38.         return SUCCESS;
  39. }

  40. /*
  41. int main( void )
  42. {
  43.         char s[80];
  44.         sprintf(s,"%s"," aaaaaa ");
  45.         printf("=== strlen = %d === \n",strlen(s));
  46.         trim(s);
  47.         printf("=== len = %d ===\n",strlen(s));
  48.         return 0;
  49. }
  50. */



上一篇:Wget如何克隆网站并能直接阅读
下一篇:细思极恐,一个特别容易忽视的变量内容被修改的问题。