雖然現在大部分時候寫系統都是用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
- ---------------
- 請按任意鍵繼續...