日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

C语言面向对象编程(六):配置文件解析

發布時間:2024/4/18 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C语言面向对象编程(六):配置文件解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?在實際項目中,經常會把軟件的某些選項寫入配置文件。 Windows 平臺上的 INI 文件格式簡單易用,本篇文章利用《C語言面向對象編程(五):單鏈表實現》中實現的單鏈表,設計了一個“類” ini_parser 來讀寫 INI 格式的配置文件。

? ? struct ini_parser 可以解析 INI 格式的字符串、文件,也可以將內存中的符合 INI 格式的數據寫入文件,能夠支持 Windows 、 Linux 、 Android 等多平臺。目前暫不支持選項分組功能。

? ? 功能相對簡單,直接看源碼吧。

? ? 下面是頭文件:

?

  • struct single_list;

  • ?
  • struct ini_parser {

  • struct single_list * keyvalues;

  • int (*parse_file)(struct ini_parser *, const char * file);

  • int (*parse_string)(struct ini_parser *, const char *text);

  • char * (*value)(struct ini_parser *, const char * key);

  • void (*set_value)(struct ini_parser *, const char * key, const char * value);

  • void (*remove)(struct ini_parser *, const char *key);

  • int (*save_to_file)(struct ini_parser *, const char * file);

  • void (*deletor)(struct ini_parser *ini);

  • };

  • ?
  • struct ini_parser * new_ini_parser();

  • ? ? struct init_parser 的聲明符合我們在本系列文章中提到的面向對象框架,需要說明的是,一旦 deletor 方法被調用, ini_parser 的實例將不再允許訪問。

    ?

    ? ? 下面是源文件:

    ?

  • #include "ini_parser.h"

  • #include <stdio.h>

  • #include <string.h>

  • ?
  • struct tag_value_pair{

  • struct slist_node node;

  • char * szTag;

  • char * szValue;

  • };

  • typedef struct tag_value_pair tag_value;

  • ?
  • static void _tag_value_free(struct slist_node *node)

  • {

  • if(node) delete_tag_value_pair(node);

  • }

  • ?
  • static int _tag_value_hittest(struct slist_node * node, void *key)

  • {

  • return strcmp((char*)tag, ((struct tag_value_pair*)node)->szTag);

  • }

  • ?
  • static struct single_list * new_tag_value_list()

  • {

  • return new_single_list(_tag_value_free, _tag_value_hittest);

  • }

  • ?
  • static struct tag_value_pair *new_tag_value_pair()

  • {

  • struct tag_value_pair * pair = (struct tag_value_pair *)malloc(sizeof(struct tag_value_pair));

  • pair->node.next = 0;

  • pair->szTag = 0;

  • pair->szValue = 0;

  • return pair;

  • }

  • ?
  • static struct tag_value_pair * make_tag_value_pair(char * tag, char * value)

  • {

  • struct tag_value_pair *pair = 0;

  • if(!tag || !value)return 0;

  • ?
  • pair = (struct tag_value_pair*)malloc(sizeof(struct tag_value_pair));

  • pair->szTag = strdup(tag);

  • pair->szValue = strdup(value);

  • pair->node.next = 0;

  • return pair;

  • }

  • ?
  • ?
  • static struct tag_value_pair * parse_line(char *line, int len)

  • {

  • struct tag_value_pair * pair = 0;

  • int count = 0;

  • char * p = line;

  • char * end = 0;m

  • char * start = line;

  • if(!p) return 0;

  • while(*p == ' ') ++p;

  • ?
  • ?
  • /*blank line*/

  • if(p - line == len ||

  • *p == '\r' ||

  • *p == '\n' ||

  • *p == '\0') return 0;

  • ?
  • /*do not support group*/

  • if(*p == '[') return 0;

  • /*comments*/

  • if(*p == '#') return 0;

  • ?
  • /* extract key */

  • start = p;

  • end = line + len;

  • while(*p != '=' && p!= end) ++p;

  • if(p == end)

  • {

  • /* none '=' , invalid line */

  • return 0;

  • }

  • end = p - 1;

  • while(*end == ' ') --end; /* skip blank at the end */

  • count = end - start + 1;

  • ?
  • pair = new_tag_value_pair();

  • pair->szTag = malloc(count + 1);

  • strncpy(pair->szTag, start, count);

  • pair->szTag[count] = 0;

  • ?
  • /* extract value */

  • ++p;

  • end = line + len; /* next pos of the last char */

  • while( *p == ' ' && p != end) ++p;

  • if(p == end)

  • {

  • delete_tag_value_pair(pair);

  • return 0;

  • }

  • start = p;

  • --end; /* to the last char */

  • if(*end == '\n') { *end = 0; --end; }

  • if(*end == '\r') { *end = 0; --end; }

  • count = end - start + 1;

  • if(count > 0)

  • {

  • pair->szValue = malloc(count + 1);

  • strncpy(pair->szValue, start, count);

  • pair->szValue[count] = 0;

  • }

  • ?
  • /* release empty key-value pair */

  • if(!pair->szValue)

  • {

  • delete_tag_value_pair(pair);

  • return 0;

  • }

  • ?
  • return pair;

  • }

  • ?
  • static int _parse_file(struct ini_parser * ini, const char *file){

  • FILE * fp = fopen(file, "r");

  • if(fp)

  • {

  • struct tag_value_pair * pair = 0;

  • char buf[1024] = {0};

  • while(fgets(buf, 1024, fp))

  • {

  • pair = parse_line(buf, strlen(buf));

  • if(pair)

  • {

  • ini->keyvalues->add(ini->keyvalues, pair);

  • }

  • }

  • fclose(fp);

  • return ini->keyvalues->size;

  • }

  • return -1;

  • }

  • ?
  • static int _parse_text(struct ini_parser * ini, const char * text){

  • char *p = text;

  • char * start = 0;

  • struct tag_value_pair * pair = 0;

  • if(!text) return -1;

  • ?
  • while(1)

  • {

  • start = p;

  • while(*p != '\n' && *p != '\0' )++p;

  • if(*p == '\0') break;

  • ?
  • pair = parse_line(start, p - start);

  • if(pair) ini->keyvalues->add(ini->keyvalues, pair);

  • ?
  • ++p;

  • }

  • ?
  • return ini->keyvalues->size;

  • }

  • ?
  • static char * _value(struct ini_parser * ini, const char * key){

  • struct tag_value_pair * pair = NODE_T(ini->keyvalues->find_by_key(ini->keyvalues, key), struct tag_value_pair);

  • if(pair) return pair->szValue;

  • return 0;

  • }

  • ?
  • static void _set_value(struct ini_parser * ini, const char * key, const char *value){

  • struct tag_value_pair * pair = NODE_T(ini->keyvalues->find_by_key(ini->keyvalues, key), struct tag_value_pair);

  • if(pair)

  • {

  • if(pair->szValue) free(pair->szValue);

  • pair->szValue = strdup(value);

  • }

  • else

  • {

  • ini->keyvalues->add(ini->keyvalues, make_tag_value_pair(key, value));

  • }

  • }

  • ?
  • static void _remove(struct ini_parser * ini, const char * key){

  • struct tag_value_pair * pair = NODE_T(ini->keyvalues->find_by_key(ini->keyvalues, key), struct tag_value_pair);

  • if(pair)ini->keyvalues->remove(ini->keyvalues, pair);

  • }

  • ?
  • static void write_keyvalue(struct tag_value_pair * pair, FILE *fp)

  • {

  • fputs(pair->szTag, fp);

  • fputc('=', fp);

  • fputs(pair->szValue, fp);

  • fputc('\n', fp);

  • }

  • ?
  • static int _save_to_file(struct ini_parser * ini, const char * file){

  • if(ini->keyvalues->size > 0)

  • {

  • FILE * fp = fopen(file, "w");

  • if(fp)

  • {

  • struct tag_value_pair * pair = NODE_T(ini->keyvalues->head,struct tag_value_pair);

  • while(pair != 0)

  • {

  • write_keyvalue(pair, fp);

  • pair = NODE_T(pair->node.next, struct tag_value_pair);

  • }

  • ?
  • fclose(fp);

  • return 0;

  • }

  • }

  • return -1;

  • }

  • ?
  • static void _delete_ini_parser(struct ini_parser *ini){

  • if(ini)

  • {

  • ini->keyvalues->deletor(ini->keyvalues);

  • free(ini);

  • }

  • }

  • ?
  • struct ini_parser * new_ini_parser(){

  • struct ini_parser * ini = (struct ini_parser*)malloc(sizeof(struct ini_parser));

  • ini->keyvalues = new_tag_value_list();

  • ini->parse_file = _parse_file;

  • ini->parse_string = _parse_text;

  • ini->value = _value;

  • ini->set_value = _set_value;

  • ini->remove = _remove;

  • ini->save_to_file = _save_to_file;

  • ini->deletor = _delete_ini_parser;

  • return ini;

  • }

  • ? ? 下面是簡單的測試代碼:

  • static char * g_szIniString = "#abc\nfirst=2\nsecond\nname=charli zhang \n";

  • ?
  • static void ini_parser_test_string()

  • {

  • struct ini_parser * ini = new_ini_parser();

  • int size = ini->parse_string(ini, g_szIniString);

  • ?
  • assert( size > 0);

  • assert( ini->value(ini, "second") == 0 );

  • assert( ini->value(ini, "abc") == 0);

  • assert( ini->value(ini, "name") != NULL );

  • assert( ini->value(ini, "first") != NULL);

  • ?
  • printf("ini string: %s\n", g_szIniString);

  • printf("key-value pairs count = %d\n", size);

  • printf("key \'name\'', value = %s\n", ini->value(ini, "name"));

  • printf("key \'first\'', value = %s\n", ini->value(ini, "first"));

  • ?
  • ini->set_value(ini, "baidu", "hahaha");

  • ini->save_to_file(ini, "write.conf");

  • ?
  • ini->remove(ini, "first");

  • ini->save_to_file(ini, "write2.conf");

  • ?
  • ini->deletor(ini);

  • }

  • ?
  • static void ini_parser_test_file()

  • {

  • struct ini_parser * ini = new_ini_parser();

  • int size = ini->parse_file(ini, "test.conf");

  • ?
  • assert( size > 0);

  • assert( ini->value(ini, "second") == 0 );

  • assert( ini->value(ini, "abc") == 0);

  • assert( ini->value(ini, "name") != NULL );

  • assert( ini->value(ini, "first") != NULL);

  • ?
  • printf("ini string: %s\n", g_szIniString);

  • printf("key-value pairs count = %d\n", size);

  • printf("key \'name\'', value = %s\n", ini->value(ini, "name"));

  • printf("key \'first\'', value = %s\n", ini->value(ini, "first"));

  • printf("key \'baidu\'', value = %s\n", ini->value(ini, "baidu"));

  • ?
  • ini->deletor(ini);

  • }

  • ?
  • void ini_parser_test()

  • {

  • ini_parser_test_string();

  • ini_parser_test_file();

  • }

  • ?

    ?

    ? ? struct ini_parser 已經運用在實際的項目中,目前為止沒發現什么問題。

    總結

    以上是生活随笔為你收集整理的C语言面向对象编程(六):配置文件解析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。