LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1127|回复: 12

读取配置信息

[复制链接]
发表于 2003-8-26 15:09:22 | 显示全部楼层 |阅读模式
请问如何用c语言实现读取配置文件中的配置信息?

文件格式:

“#”号表明该行的信息为注释信息

配置信息格式如下
servername = xxxx
发表于 2003-8-26 15:55:38 | 显示全部楼层
If those info as an environment variable,

use "getenv" to get it.
 楼主| 发表于 2003-8-26 16:40:48 | 显示全部楼层
我要操作的配置文件是一个自定义的普通文件,而不是环境变量
该怎么样处理???
发表于 2003-8-26 17:38:41 | 显示全部楼层
是不是可以利用编译原理中的词法分析?
 楼主| 发表于 2003-8-26 19:07:37 | 显示全部楼层
没有学过哦
有不有其他的办法呀?
发表于 2003-8-26 19:14:26 | 显示全部楼层
可以看一下C库的字符串处理函数,不过写起来还是有点麻烦,回头我给你写一个试试。
发表于 2003-8-26 19:24:12 | 显示全部楼层
看看qt库,里面可以用正则表达式。
qregexp
发表于 2003-8-27 00:26:27 | 显示全部楼层
写了一个模块,一开始没怎么规划,所以看着有点难受,比如函数的名字之类的,文件名也有点太短了。
配置按key=value的形式。
头文件:rc.h

  1. #ifndef RC_H
  2. #define RC_H

  3. int rc_init(const char *filename); /*初始化rc*/
  4. void rc_destroy(void); /*释放rc*/

  5. int rc_number(void); /*rc数目*/

  6. const char *rc_next(void); /*下一个条目*/
  7. void rc_rewind(void); /*回到开头*/
  8. const char *rc_getKey(void); /*取得当前的key*/
  9. const char *rc_getValue(void); /*取得当前的value*/

  10. const char *rc_getVByKey(const char *key); /*按key搜索value*/

  11. const char *rc_getKByNum(int index); /*按index取得key*/
  12. const char *rc_getVByNum(int index); /*anindex取得value*/

  13. int rc_exist(const char *key); /*测试key是否存在*/

  14. #endif

复制代码

.c文件:rc.c

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <errno.h>
  4. #include "rc.h"

  5. static char *(*rc)[2];
  6. static int number;
  7. static int current;

  8. static int test(void);
  9. static int getrc(FILE *);
  10. static char *getstring(char *);

  11. int
  12. rc_init(const char *filename)
  13. {
  14.   FILE *fp;
  15.   char err[100];

  16.   if((fp = fopen(filename, "r")) == NULL){
  17.     sprintf(err, "connot open %s", filename);
  18.     perror(err);
  19.     return(-1);
  20.   }
  21.   if(getrc(fp)){
  22.     fclose(fp);
  23.     return(-1);
  24.   }

  25.   fclose(fp);
  26.   return(0);
  27. }

  28. void
  29. rc_destroy(void)
  30. {
  31.   int i;

  32.   if(!test())
  33.     return;
  34.   
  35.   for(i = 0; i < number; i++){
  36.     free(rc[i][0]);
  37.     free(rc[i][1]);
  38.   }
  39.   free(rc);
  40. }

  41. int
  42. rc_number(void)
  43. {
  44.   if(!test())
  45.     return(0);
  46.   
  47.   return(number);
  48. }

  49. const char *
  50. rc_next(void)
  51. {
  52.   if(!test())
  53.     return(0);
  54.   
  55.   if(++current < number)
  56.     return(rc[current][0]);
  57.   return(NULL);
  58. }

  59. void
  60. rc_rewind(void)
  61. {
  62.   if(!test())
  63.     return;
  64.   
  65.   current = 0;
  66. }

  67. const char *
  68. rc_getKey(void)
  69. {
  70.   if(!test())
  71.     return(0);
  72.   
  73.   return(rc[current][0]);
  74. }

  75. const char *
  76. rc_getValue(void)
  77. {
  78.   if(!test())
  79.     return(0);
  80.   
  81.   return(rc[current][1]);
  82. }

  83. const char *
  84. rc_getVByKey(const char *key)
  85. {
  86.   int i;

  87.   if(!test())
  88.     return(0);
  89.   
  90.   for(i = 0; i < number; i++)
  91.     if(!strcasecmp(key, rc[i][0]))
  92.       return(rc[i][1]);
  93.   return(NULL);
  94. }

  95. const char *
  96. rc_getKByNum(int index)
  97. {
  98.   if(!test())
  99.     return(0);
  100.   
  101.   return(rc[index][0]);
  102. }

  103. const char *
  104. rc_getVByNum(int index)
  105. {
  106.   if(!test())
  107.     return(0);
  108.   
  109.   return(rc[index][1]);
  110. }

  111. int
  112. rc_exist(const char *key)
  113. {
  114.   int i;

  115.   if(!test())
  116.     return(0);
  117.   
  118.   for(i = 0; i < number; i++)
  119.     if(!strcasecmp(key, rc[i][0]))
  120.       return(1);
  121.   return(0);
  122. }

  123. int
  124. getrc(FILE *fp)
  125. {
  126.   char s[1024], *p, *t;
  127.   
  128.   while(fgets(s, 1023, fp)){
  129.     if((p = strchr(s, '#')) != NULL)
  130.       *p = '\0';
  131.     t = s + strspn(s, " \t\n");
  132.     if(*t == '\0')
  133.       continue;
  134.     if((p = strchr(t, '=')) != NULL)
  135.       *p = '\0';
  136.     if((t = getstring(t)) == NULL)
  137.       continue;
  138.     rc = (char *(*)[2])realloc(rc, (number + 1) * sizeof(char *[2]));
  139.     rc[number][0] = (char *)malloc(strlen(t) + 1);
  140.     strcpy(rc[number][0], t);
  141.     if(p && (t = getstring(p + 1))){
  142.       rc[number][1] = (char *)malloc(strlen(t) + 1);
  143.       strcpy(rc[number][1], t);
  144.     }else
  145.       rc[number][1] = NULL;
  146.     number++;
  147.   }
  148.   if(ferror(fp))
  149.     return(-1);
  150.   return(0);
  151. }

  152. int
  153. test(void)
  154. {
  155.   if(number == 0 || rc == NULL)
  156.     return(0);
  157.   return(1);
  158. }

  159. char *
  160. getstring(char *s)
  161. {
  162.   char *result, *t;
  163.   int n;

  164.   result = s + strspn(s, " \t\n");
  165.   if(*result == '\0')
  166.     return(NULL);
  167.   s = result;
  168.   while(*s){
  169.     s = s + strcspn(s, " \t\n");
  170.     t = s;
  171.     s = s + strspn(s, " \t\n");
  172.   }
  173.   *t = '\0';
  174.   return(result);
  175. }

复制代码
发表于 2003-8-27 00:28:28 | 显示全部楼层
测试文件
main.c

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "rc.h"

  4. int
  5. main(void)
  6. {
  7.   char *rcfile = "./testrc";
  8.   char buf[80];
  9.   const char *t;
  10.   int i;

  11.   if(rc_init(rcfile))
  12.     exit(-1);
  13.   
  14.   printf("print rc (rc_next):\n");
  15.   printf("%s: %s\n", rc_getKey(), rc_getValue());
  16.   while(rc_next()) /*用rc_next遍历*/
  17.     printf("%s: %s\n", rc_getKey(), rc_getValue());

  18.   printf("\nprint rc (index):\n");
  19.   for(i = rc_number() - 1; i >= 0; i--) /*用index反向遍历*/
  20.     printf("%s: %s\n", rc_getKByNum(i), rc_getVByNum(i));

  21.   printf("\nPlease input a key: ");
  22.   while(fgets(buf, 79, stdin)){ /*输入key取得value*/
  23.     buf[strlen(buf) - 1] = '\0';
  24.     printf("%s: ", buf);
  25.     if((t = rc_getVByKey(buf)) == NULL){
  26.       if(rc_exist(buf))
  27.         printf("NULL\n");
  28.       else
  29.         printf("not found\n");
  30.     }else
  31.       printf("%s\n", t);
  32.     printf("\nPlease input a key: ");
  33.   }
  34.   printf("\n");
  35.   rc_destroy();
  36.   exit(0);
  37. }

复制代码

testrc

  1. #测试用的,所以有点怪
  2. one=123
  3. two =         321#dd
  4. #
  5.         #d
  6.         three#=22
  7.         four         =         4
  8.          = 66
  9.          abc de = ll

复制代码

用 gcc main.c rc.c -o rc 编译
发表于 2003-8-27 00:38:31 | 显示全部楼层
使用的时候必须先调用rc_init,最后调用rc_destroy释放资源。

程序只是初步写的,能运行,不过要真当一个可重用的模块,还有很多工作要做。
读简单的配置文件应该没问题,没有提供写入的功能。
程序是用一个数组实现的,搜索的速度就比较慢,不过一般配置文件都不大,不影响速度。
还有一些问题没有处理,比如几个key相同的情况,搜索的话就只能得到第一个,等等。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表