在一个跨平台( Android 、Windows、Linux )项目中配置文件用 INI 格式,自己写了个解析库,纯C语言的,简单好用。

可以解析 INI 格式的字符串、解析文件、保存到文件。

下面是头文件:

#ifndef INI_PARSER_H#define INI_PARSER_H#ifdef __cplusplusextern "C" {#endifstruct tag_value_list;struct ini_parser {    struct tag_value_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);};struct ini_parser * new_ini_parser();void delete_ini_parser(struct ini_parser *);#ifdef __cplusplus}#endif#endif // INI_PARSER_H

下面是源文件:

#include "ini_parser.h"#include <stdio.h>#include <string.h>#include "tag_value.h"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;    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 = ini->keyvalues->find_by_tag(ini->keyvalues, key);    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 = ini->keyvalues->find_by_tag(ini->keyvalues, key);    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 = ini->keyvalues->find_by_tag(ini->keyvalues, key);    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 = ini->keyvalues->head;            while(pair != ini->keyvalues->tail)            {                write_keyvalue(pair, fp);                pair = pair->next;            }            if(pair)write_keyvalue(pair, fp);            fclose(fp);            return 0;        }    }    return -1;}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;    return ini;}void delete_ini_parser(struct ini_parser *ini){    if(ini)    {        delete_tag_value_list(ini->keyvalues);        free(ini);    }}

测试代码:

#include "util/ini_parser.h"#include "ini_test.h"#include <stdio.h>#include <assert.h>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");    delete_ini_parser(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"));    delete_ini_parser(ini);}void ini_parser_test(){    ini_parser_test_string();    ini_parser_test_file();}

测试了解析字符串、文件、增、删、写文件,都没什么大问题。


更多相关文章

  1. Android(安卓)Studio如何导入第三方库进行JNI编程
  2. MTK Android(安卓)P 开机无动画,无铃声问题和开机铃声不同步,首次
  3. android linux镜像文件下载, ubuntu下载地址!
  4. Android(安卓)解析Json
  5. toLowerCase()方法 toUpperCase()方法
  6. 基于Cortex-a15的模拟环境搭建——Guest Android
  7. 【凯子哥带你学Framework】Activity界面显示全解析(下)
  8. the currently displayed page contains invalid values
  9. 【Android(安卓)Developers Training】 3. 构建一个简单UI

随机推荐

  1. 《Android面试宝典》学习笔记(第四章:对话
  2. Android界面开发问题总结
  3. Android设置无标题窗口
  4. Android学习笔记―第十一章 Fragment
  5. Android中Timer与Thread的使用
  6. Androd Html Demo js与java相互调用
  7. Android(安卓)中的设置关于手机中的型号
  8. mac下Android(安卓)apk 破解流程
  9. Android(安卓)Bundle类
  10. [Android(安卓)Pro] Android签名与认证详