Linux C 创建配置文件小模板

来源:互联网 发布:mac sftp 编辑:程序博客网 时间:2024/06/05 18:20

虽然现在大部分时候写系统都是用xml解析配置文件了, 但有时一些小型的东西配置项不多且关系并不复杂的时候, 仅用一两个小函数读取配置文件的方式也不错, 这样的话, 配置文件也可以写得很简单了

  第一步, 先写一个最简单版本的,

  1.配置项以行为单位, 配置项(key)在前, 值(value)在后, 中间用空格分隔, key和value可以分别用单引号和双引号引起来

  2.以#开头的为注释行

 

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <locale>  
  3.   
  4. void GetArg(char* arg, int size, char **pp)  
  5. {  
  6.     char *p = NULL;  
  7.     char *q = NULL;  
  8.     int quote = 0;  
  9.   
  10.     p = *pp;  
  11.     while(isspace(*p))  
  12.         p++;  
  13.     q = arg;  
  14.     if (*p == '/"' || *p == '/'')  
  15.         quote = *p++;  
  16.     while(1)  
  17.     {  
  18.         if (quote && quote == *p)  
  19.         {  
  20.             p++;  
  21.             break;  
  22.         }  
  23.         if (quote == 0 && (isspace(*p) || *p =='/0'))  
  24.             break;  
  25.         if ((q- arg) < (size - 1))  
  26.             *q++ = *p++;  
  27.     }  
  28.     *q = '/0';  
  29.     *pp = p;  
  30. }  
  31.   
  32. bool ParseConfig(const char *file_name)  
  33. {  
  34.     FILE *fp;  
  35.     if ((fp = fopen(file_name, "r")) == NULL)  
  36.     {  
  37.         printf("fopen() failed/n");  
  38.         return false;  
  39.     }  
  40.   
  41.     char line_buf[1024] = {0};  
  42.     char key[64] = {0};  
  43.     char value[1024] = {0};  
  44.     char *p = NULL;  
  45.   
  46.     while(1)  
  47.     {  
  48.         if (fgets(line_buf, sizeof(line_buf), fp) == NULL)  
  49.             break;  
  50.         p = line_buf;  
  51.         while(isspace(*p))  
  52.             p++;  
  53.         if (*p == '/0' || *p == '#')  
  54.             continue;  
  55.   
  56.         GetArg(key, sizeof(key), &p);  
  57.         GetArg(value, sizeof(value), &p);  
  58.         printf("%s = %s/n", key, value);  
  59.     }  
  60.   
  61.     return true;  
  62. }  
  63.   
  64. int main(int argc, char *argv[])  
  65. {  
  66.     ParseConfig("my_config_1.txt");  
  67.   
  68.     return 0;  
  69. }  

  测试文件my_config_1.txt:

 

[cpp] view plaincopy
  1. #asdfg  
  2. file_name "my_config_1.txt"  
  3. author chef  
  4. time '2010-12-24'  

  VS2005输出结果:

   

[cpp] view plaincopy
  1. file_name = my_config_1.txt  
  2. author = chef  
  3. time = 2010-12-24  
  4. 请按任意键继续...  

好了, 在这个基础上, 我们可以根据自身实际需求增加一些功能, 例如下面的这个例子为配置文件中配置一些学生的信息, 程序将它读出并放入链表(链表可能写得很蹩脚, 有错误请提出)里面, 有一定的配置错误检测, 你也可以自己添加一些错误检测

 

[cpp] view plaincopy
  1. #include <stdio.h>  
  2. #include <locale>  
  3.   
  4. struct Student  
  5. {  
  6.     char name[64];  
  7.     int    age;  
  8.     int    math;  
  9.     int    chinese;  
  10.     int    english;  
  11.     Student *next;  
  12. };  
  13.   
  14. Student *last = NULL;  
  15. Student *first = NULL;  
  16.   
  17. void GetArg(char* arg, int size, char **pp)  
  18. {  
  19.     char *p = NULL;  
  20.     char *q = NULL;  
  21.     int quote = 0;  
  22.   
  23.     p = *pp;  
  24.     while(isspace(*p))  
  25.         p++;  
  26.     q = arg;  
  27.     if (*p == '/"' || *p == '/'')  
  28.         quote = *p++;  
  29.     while(1)  
  30.     {  
  31.         if (quote && quote == *p)  
  32.         {  
  33.             p++;  
  34.             break;  
  35.         }  
  36.         if (quote == 0 && (isspace(*p) || *p =='/0'))  
  37.             break;  
  38.         if ((q- arg) < (size - 1))  
  39.             *q++ = *p++;  
  40.     }  
  41.     *q = '/0';  
  42.     *pp = p;  
  43. }  
  44.   
  45. bool ParseConfig(const char *file_name)  
  46. {  
  47.     FILE *fp;  
  48.     if ((fp = fopen(file_name, "r")) == NULL)  
  49.     {  
  50.         printf("fopen() failed/n");  
  51.         return false;  
  52.     }  
  53.   
  54.     char line_buf[1024] = {0};  
  55.     char key[64] = {0};  
  56.     char value[1024] = {0};  
  57.     char *p = NULL;  
  58.     bool tag = false;  
  59.     int score = 0;  
  60.   
  61.     while(1)  
  62.     {  
  63.         if (fgets(line_buf, sizeof(line_buf), fp) == NULL)  
  64.             break;  
  65.         p = line_buf;  
  66.         while(isspace(*p))  
  67.             p++;  
  68.         if (*p == '/0' || *p == '#')  
  69.             continue;  
  70.   
  71.         GetArg(key, sizeof(key), &p);  
  72.   
  73.         if (!_stricmp(key, "file_name"))    //windows, _stricmp, linux, strcasecmp    
  74.         {  
  75.             GetArg(value, sizeof(value), &p);  
  76.             printf("file_name = %s/n", value);  
  77.         }  
  78.         else if (!_stricmp(key, "author"))  
  79.         {  
  80.             GetArg(value, sizeof(value), &p);  
  81.             printf("author = %s/n", value);  
  82.         }  
  83.         else if (!_stricmp(key, "time"))  
  84.         {  
  85.             GetArg(value, sizeof(value), &p);  
  86.             printf("time = %s/n", value);  
  87.         }  
  88.         else if (!_stricmp(key, "<Student"))  
  89.         {  
  90.             if (tag)  
  91.                 printf("Already in a tag/n");  
  92.             else  
  93.             {  
  94.                 tag = true;  
  95.                 Student *stu = new Student;  
  96.                 last->next = stu;  
  97.                 last = stu;  
  98.                 last->next = NULL;  
  99.                 GetArg(value, sizeof(value), &p);  
  100.                 strcpy(last->name, value);  
  101.                 last->name[strlen(last->name)-1] = '/0';  
  102.             }  
  103.         }  
  104.         else if (!_stricmp(key, "age"))  
  105.         {  
  106.             if (tag)  
  107.             {  
  108.                 GetArg(value, sizeof(value), &p);  
  109.                 last->age = atoi(value);  
  110.             }  
  111.         }  
  112.         else if (!_stricmp(key, "math"))  
  113.         {  
  114.             if (tag)  
  115.             {  
  116.                 GetArg(value, sizeof(value), &p);  
  117.                 last->math = atoi(value);  
  118.             }  
  119.         }  
  120.         else if (!_stricmp(key, "chinese"))  
  121.         {  
  122.             if (tag)  
  123.             {  
  124.                 GetArg(value, sizeof(value), &p);  
  125.                 last->chinese = atoi(value);  
  126.             }  
  127.         }  
  128.         else if (!_stricmp(key, "english"))  
  129.         {  
  130.             if (tag)  
  131.             {  
  132.                 GetArg(value, sizeof(value), &p);  
  133.                 last->english = atoi(value);  
  134.             }  
  135.         }  
  136.         else if (!_stricmp(key, "</Student>"))  
  137.         {  
  138.             if (tag)  
  139.                 tag = false;  
  140.             else  
  141.                 printf("no match tag head!/n");  
  142.         }  
  143.         else  
  144.         {  
  145.             printf("%s is not need!/n");  
  146.         }  
  147.   
  148.     }  
  149.   
  150.     return true;  
  151. }  
  152.   
  153. int main(int argc, char *argv[])  
  154. {  
  155.     last = (Student*)malloc(sizeof(Student));  
  156.     first = last;  
  157.   
  158.     ParseConfig("my_config.txt");  
  159.   
  160.     Student *p = first->next;  
  161.     while(p)  
  162.     {  
  163.         printf("---------------/n");  
  164.         printf("name: %s/n", p->name);  
  165.         printf("age: %d/n", p->age);  
  166.         printf("math: %d/n", p->math);  
  167.         printf("chinese: %d/n", p->chinese);  
  168.         printf("english: %d/n", p->english);  
  169.         printf("---------------/n");  
  170.           
  171.         if (p->next == NULL)  
  172.             break;  
  173.         else  
  174.             p = p->next;  
  175.     }  
  176.   
  177.         //clear the linked list, since the program is over, i ignore it  
  178.   
  179.     return 0;  
  180. }  

  测试配置文件my_config.txt:

[cpp] view plaincopy
  1. #asdfg  
  2. file_name  "my_config.txt"  
  3. author      chef  
  4. time       '2010-12-24'  
  5.   
  6. <Student tom>  
  7. math    60  
  8. english 70  
  9. age     13  
  10. chinese 80  
  11. </Student>  
  12.   
  13. <Student jerry>  
  14. english 66  
  15. age     8  
  16. chinese 88  
  17. math    99  
  18. </Student>  

  VS2005输出结果:

[cpp] view plaincopy
  1. file_name = my_config.txt  
  2. author = chef  
  3. time = 2010-12-24  
  4. ---------------  
  5. name: tom  
  6. age: 13  
  7. math: 60  
  8. chinese: 80  
  9. englist: 70  
  10. ---------------  
  11. ---------------  
  12. name: jerry  
  13. age: 8  
  14. math: 99  
  15. chinese: 88  
  16. english: 66  
  17. ---------------  
  18. 请按任意键继续...  

0 0