虽然现在大部分时候写系统都是用xml解析配置文件了, 但有时一些小型的东西配置项不多且关系并不复杂的时候, 仅用一两个小函数读取配置文件的方式也不错, 这样的话, 配置文件也可以写得很简单了
第一步, 先写一个最简单版本的,
1.配置项以行为单位, 配置项(key)在前, 值(value)在后, 中间用空格分隔, key和value可以分别用单引号和双引号引起来
2.以#开头的为注释行
- #include <stdio.h>
- #include <locale>
- void GetArg(char* arg, int size, char **pp)
- {
- char *p = NULL;
- char *q = NULL;
- int quote = 0;
- p = *pp;
- while(isspace(*p))
- p++;
- q = arg;
- if (*p == '/"' || *p == '/'')
- quote = *p++;
- while(1)
- {
- if (quote && quote == *p)
- {
- p++;
- break;
- }
- if (quote == 0 && (isspace(*p) || *p =='/0'))
- break;
- if ((q- arg) < (size - 1))
- *q++ = *p++;
- }
- *q = '/0';
- *pp = p;
- }
- bool ParseConfig(const char *file_name)
- {
- FILE *fp;
- if ((fp = fopen(file_name, "r")) == NULL)
- {
- printf("fopen() failed/n");
- return false;
- }
- char line_buf[1024] = {0};
- char key[64] = {0};
- char value[1024] = {0};
- char *p = NULL;
- while(1)
- {
- if (fgets(line_buf, sizeof(line_buf), fp) == NULL)
- break;
- p = line_buf;
- while(isspace(*p))
- p++;
- if (*p == '/0' || *p == '#')
- continue;
- GetArg(key, sizeof(key), &p);
- GetArg(value, sizeof(value), &p);
- printf("%s = %s/n", key, value);
- }
- return true;
- }
- int main(int argc, char *argv[])
- {
- ParseConfig("my_config_1.txt");
- return 0;
- }
测试文件my_config_1.txt:
- #asdfg
- file_name "my_config_1.txt"
- author chef
- time '2010-12-24'
VS2005输出结果:
- file_name = my_config_1.txt
- author = chef
- time = 2010-12-24
- 请按任意键继续...
好了, 在这个基础上, 我们可以根据自身实际需求增加一些功能, 例如下面的这个例子为配置文件中配置一些学生的信息, 程序将它读出并放入链表(链表可能写得很蹩脚, 有错误请提出)里面, 有一定的配置错误检测, 你也可以自己添加一些错误检测
- #include <stdio.h>
- #include <locale>
- struct Student
- {
- char name[64];
- int age;
- int math;
- int chinese;
- int english;
- Student *next;
- };
- Student *last = NULL;
- Student *first = NULL;
- void GetArg(char* arg, int size, char **pp)
- {
- char *p = NULL;
- char *q = NULL;
- int quote = 0;
- p = *pp;
- while(isspace(*p))
- p++;
- q = arg;
- if (*p == '/"' || *p == '/'')
- quote = *p++;
- while(1)
- {
- if (quote && quote == *p)
- {
- p++;
- break;
- }
- if (quote == 0 && (isspace(*p) || *p =='/0'))
- break;
- if ((q- arg) < (size - 1))
- *q++ = *p++;
- }
- *q = '/0';
- *pp = p;
- }
- bool ParseConfig(const char *file_name)
- {
- FILE *fp;
- if ((fp = fopen(file_name, "r")) == NULL)
- {
- printf("fopen() failed/n");
- return false;
- }
- char line_buf[1024] = {0};
- char key[64] = {0};
- char value[1024] = {0};
- char *p = NULL;
- bool tag = false;
- int score = 0;
- while(1)
- {
- if (fgets(line_buf, sizeof(line_buf), fp) == NULL)
- break;
- p = line_buf;
- while(isspace(*p))
- p++;
- if (*p == '/0' || *p == '#')
- continue;
- GetArg(key, sizeof(key), &p);
- if (!_stricmp(key, "file_name")) //windows, _stricmp, linux, strcasecmp
- {
- GetArg(value, sizeof(value), &p);
- printf("file_name = %s/n", value);
- }
- else if (!_stricmp(key, "author"))
- {
- GetArg(value, sizeof(value), &p);
- printf("author = %s/n", value);
- }
- else if (!_stricmp(key, "time"))
- {
- GetArg(value, sizeof(value), &p);
- printf("time = %s/n", value);
- }
- else if (!_stricmp(key, "<Student"))
- {
- if (tag)
- printf("Already in a tag/n");
- else
- {
- tag = true;
- Student *stu = new Student;
- last->next = stu;
- last = stu;
- last->next = NULL;
- GetArg(value, sizeof(value), &p);
- strcpy(last->name, value);
- last->name[strlen(last->name)-1] = '/0';
- }
- }
- else if (!_stricmp(key, "age"))
- {
- if (tag)
- {
- GetArg(value, sizeof(value), &p);
- last->age = atoi(value);
- }
- }
- else if (!_stricmp(key, "math"))
- {
- if (tag)
- {
- GetArg(value, sizeof(value), &p);
- last->math = atoi(value);
- }
- }
- else if (!_stricmp(key, "chinese"))
- {
- if (tag)
- {
- GetArg(value, sizeof(value), &p);
- last->chinese = atoi(value);
- }
- }
- else if (!_stricmp(key, "english"))
- {
- if (tag)
- {
- GetArg(value, sizeof(value), &p);
- last->english = atoi(value);
- }
- }
- else if (!_stricmp(key, "</Student>"))
- {
- if (tag)
- tag = false;
- else
- printf("no match tag head!/n");
- }
- else
- {
- printf("%s is not need!/n");
- }
- }
- return true;
- }
- int main(int argc, char *argv[])
- {
- last = (Student*)malloc(sizeof(Student));
- first = last;
- ParseConfig("my_config.txt");
- Student *p = first->next;
- while(p)
- {
- printf("---------------/n");
- printf("name: %s/n", p->name);
- printf("age: %d/n", p->age);
- printf("math: %d/n", p->math);
- printf("chinese: %d/n", p->chinese);
- printf("english: %d/n", p->english);
- printf("---------------/n");
- if (p->next == NULL)
- break;
- else
- p = p->next;
- }
- //clear the linked list, since the program is over, i ignore it
- return 0;
- }
测试配置文件my_config.txt:
- #asdfg
- file_name "my_config.txt"
- author chef
- time '2010-12-24'
- <Student tom>
- math 60
- english 70
- age 13
- chinese 80
- </Student>
- <Student jerry>
- english 66
- age 8
- chinese 88
- math 99
- </Student>
VS2005输出结果:
- file_name = my_config.txt
- author = chef
- time = 2010-12-24
- ---------------
- name: tom
- age: 13
- math: 60
- chinese: 80
- englist: 70
- ---------------
- ---------------
- name: jerry
- age: 8
- math: 99
- chinese: 88
- english: 66
- ---------------
- 请按任意键继续...