配置文件读写工具(c语言实现)

一,
实现了一个灵活的读取或设置配置文件中的键-值中的值的功能
使用规则如下
1,键-值之间的连接符可以自定义指定,不固定
2,对配置文件的大小没有限制,可随意大小
3,键,连接符,值依次出现一行,三者之间不能有重叠
4,对于设置函数,如果不存在对应的键,则会在配置文件最后一行自动添加
5 对于每行除空格字符外第一个字符为‘#’,则该行会被当成注释行
二,有五个文件分别为conf_file.c conf_file.c test.c Makfile test.ini,
可直接通过make命令进行编译
其中conf_file.c conf_file.h为接口工具文件
test.c为测试文件
Makefile为编译指令文件
test.in测试用配置文件名
三,优点;该工具经过测试,开发人员可直接使用,节约开发效率
四 ,源码展示如下
1, conf_file.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>


/*
实现了一个灵活的读取或设置配置文件中的键-值中的值的功能
1,键-值之间的连接符可以自定义指定,不固定
2,对配置文件的大小没有限制,可随意大小
3,键,连接符,值依次出现一行,三者之间不能有重叠 
4,对于设置函数,如果不存在对应的键,则会在配置文件最后一行自动添加
5 对于每行除空格字符外第一个字符为‘#’,则该行会被当成注释行
*/ 
#define CONF_FILE_MAX_LINE_SIZE 128   //配置文件中的每行的字符个数不能超过128个 否者该行的内容会被被删掉
struct conf_file_list_str;
typedef struct conf_file_list_str{
    char str[CONF_FILE_MAX_LINE_SIZE];
    struct conf_file_list_str *next;
}CONF_FILE_LIST;


/*
***********************************************************
 *函数名:Is_ALL_Special_Character
 *功   能:判断从p开始 len长度的地址空间所指向的字符是否都为symbol
 *输   入:
 *输   出:
 *返回 值:是返回0;否者返回-1
 *说  明:
 *************************************************************
 */
static int Is_ALL_Special_Character(char *p, int len, char symbol){
    int i;
    for(i = 0; i < len; i++){
        if(p[i] != symbol) return -1;
    }
    return 0;
}



/*
***********************************************************
 *函数名:conf_file_set_value_by_key
 *功   能:根据提供的键设置配置文件中的值,如果指定的键不存在,则在最后一行添加
 *输   入:file[in]:配置文件名;key[in]:键-值中的键;symbol[in]:处于键-值之间的的符号,
         该符号必须具备将键-值区别开的能力,即键,值中不能包含该字符;value[in]:键-值中的值
 *输   出:key
 *返回 值:成功返回0,如果返回-1
 *说  明:
 *************************************************************
 */
int conf_file_set_value_by_key(const char *file, const char *key,const char symbol, const char *value){
    int ret = -1;
    FILE *pfile = fopen(file, "r");//以写模式打开文件,如果该文件不存在,则创建该文件
    if(!pfile) {
        perror(fopen);
        return -1;
    }
        
    CONF_FILE_LIST *root_node = NULL, *temp_node, *pre_node = NULL, *tail_node;
    CONF_FILE_LIST *curr_node = (CONF_FILE_LIST*)malloc(sizeof(CONF_FILE_LIST));
    curr_node ->next = NULL;
    root_node = curr_node;
    pre_node = NULL;
    char *p, *p1;
    int p_len = CONF_FILE_MAX_LINE_SIZE;
    while(fgets(curr_node->str, CONF_FILE_MAX_LINE_SIZE, pfile)){
        if(!root_node) root_node = curr_node;
        temp_node = (CONF_FILE_LIST*)malloc(sizeof(CONF_FILE_LIST));
        memset(temp_node->str, 0, CONF_FILE_MAX_LINE_SIZE);
        temp_node->next = NULL;
        curr_node->next = temp_node;
        pre_node = curr_node;
        curr_node = temp_node;
    }
    tail_node = curr_node;
    curr_node = root_node;
    //首先查收是否有换行符
    while(curr_node){
        //判断是否有换行符
        p = curr_node->str;
        p_len = CONF_FILE_MAX_LINE_SIZE;
        if(NULL == (p1 = strchr(p, '#')) || 0 != Is_ALL_Special_Character(p, p1 - p, ' ')){
            if(NULL != (p1 = strstr(p, key)) && 0 == Is_ALL_Special_Character(p, p1 - p, ' ')){
               p_len -= (p1 - p);
               p = p1;                                                                                                                                                                                             
               p += strlen(key);
               p_len -= strlen(key);
               if(NULL != (p1 = strchr(p, symbol)) && 0 == Is_ALL_Special_Character(p, p1 - p, ' ')){
                   p_len -= (p1 - p);
                   p = p1;
                   p_len --;
                   p++;
                   int temp_len = strlen(value);
                   if((p_len -2) < temp_len) 
                       goto err1;                
                   memset(p, 0, p_len);               
                   strcpy(p, value);
                   p[temp_len] = '\n';
                   p[temp_len + 1] = '\0';
                   break;
               }
            }
        }
        curr_node = curr_node->next;
    }   
    //一定是链表节点遍历到了最后一个节点
    if(curr_node == NULL){
        
        if(strlen(key) + 1 + strlen(value) > (CONF_FILE_MAX_LINE_SIZE - 3)) 
            goto err1;
        char *p = tail_node->str;
        *p = '\n';
        p++;
        strcpy(p, key);
        p += strlen(key);
        *p = symbol;
        p++;
        strcpy(p, value);
        p += strlen(value);
        *p = '\n';
        p++;
        *p = '\0';
    }else{ 
        pre_node->next = NULL;
        free(tail_node);
    }
    ret = 0;
err1:
    
    fclose(pfile);
    pfile = fopen(file, "w+");//以写模式打开文件,如果该文件不存在,则创建该文件
    curr_node = root_node;
    while(curr_node){
        fputs(curr_node->str, pfile);  
        pre_node = curr_node;
        curr_node = curr_node->next;
        free(pre_node);
    }
    fclose(pfile);
    return ret;
}

/*
***********************************************************
 *函数名:conf_file_set_value_by_key
 *功   能:根据提供的键设置配置文件中的值,如果指定的键不存在,则在最后一行添加
 *输   入:file[in]:配置文件名;key[in]:键-值中的键;symbol[in]:处于键-值之间的的符号,
         该符号必须具备将键-值区别开的能力,即键,值中不能包含该字符;value[in]:键-值中的值
 *输   出:key
 *返回 值:成功返回0,如果返回-1
 *说  明:
 *************************************************************
 */
int conf_file_get_value_by_key(const char *file,const  char *key,const char symbol, char *value){
    int ret = 0;
    FILE *pfile = fopen(file, "r");//以写模式打开文件,如果该文件不存在,则创建该文件
    if(!pfile) {
        perror(fopen);
        return -1;
    }
    CONF_FILE_LIST *root_node = NULL, *temp_node, *pre_node = NULL;
    CONF_FILE_LIST *curr_node = (CONF_FILE_LIST*)malloc(sizeof(CONF_FILE_LIST));
    curr_node ->next = NULL;
    root_node = curr_node;
    pre_node = NULL;
    char *p, *p1;
    int p_len = CONF_FILE_MAX_LINE_SIZE;
    while(fgets(curr_node->str, CONF_FILE_MAX_LINE_SIZE, pfile)){
        if(!root_node) root_node = curr_node;
        temp_node = (CONF_FILE_LIST*)malloc(sizeof(CONF_FILE_LIST));
        memset(temp_node->str, 0, CONF_FILE_MAX_LINE_SIZE);
        temp_node->next = NULL;
        curr_node->next = temp_node;
        pre_node = curr_node;
        curr_node = temp_node;
    }
    curr_node = root_node;
    //首先查收是否有换行符
    while(curr_node){
        //判断是否有换行符
        p = curr_node->str;
        p_len = CONF_FILE_MAX_LINE_SIZE;
        if(NULL == (p1 = strchr(p, '#')) || 0 != Is_ALL_Special_Character(p, p1 - p, ' ')){
            if(NULL != (p1 = strstr(p, key)) && 0 == Is_ALL_Special_Character(p, p1 - p, ' ')){
                p_len -= (p1 - p);
                p = p1;                                                                                                                                                                                        
                p += strlen(key);
                p_len -= strlen(key);
                if(NULL != (p1 = strchr(p, symbol)) && 0 == Is_ALL_Special_Character(p, p1 - p, ' ')){
                    p_len -= (p1 - p);
                    p = p1;
                    p_len --;
                    p++;
                    char temp_p[CONF_FILE_MAX_LINE_SIZE], *temp_p1 = temp_p;
                    strcpy(temp_p, p);
                    int i = 0;
                    //去除值字符串两端的字符
                    while(i < strlen(temp_p) && temp_p[i] == ' '){
                        temp_p1++;
                        i++; 
                    }
                    i = strlen(temp_p1) -1;
                    while(i >= 0 && (temp_p1[i] == ' ' || temp_p1[i] == '\n')){

                        temp_p1[i] = '\0';
                        i--;
                    }
                    if(strlen(temp_p1) == 0){
                        value[0] = '\0';
                    }else{
                        strcpy(value, temp_p);
                    }
                    goto success1;
                }
            }
        }
        curr_node = curr_node->next;
    }  
    ret = -1;
success1:
    fclose(pfile);
    curr_node = root_node;
    while(curr_node){    
        pre_node = curr_node;
        curr_node = curr_node->next;
        free(pre_node);
    }
    return ret;
}

2,conf_file.h

#ifndef CONF_FILE_H
#define CONF_FILE_H

/*
***********************************************************
 *函数名:conf_file_set_value_by_key
 *功   能:根据提供的键设置配置文件中的值,如果指定的键不存在,则在最后一行添加
 *输   入:file[in]:配置文件名;key[in]:键-值中的键;symbol[in]:处于键-值之间的的符号,
         该符号必须具备将键-值区别开的能力,即键,值中不能包含该字符;value[in]:键-值中的值
 *输   出:key
 *返回 值:成功返回0,如果返回-1
 *说  明:
 *************************************************************
 */
int conf_file_set_value_by_key(const char *file, const char *key,const char symbol, const char *value);
/*
***********************************************************
 *函数名:conf_file_set_value_by_key
 *功   能:根据提供的键设置配置文件中的值,如果指定的键不存在,则在最后一行添加
 *输   入:file[in]:配置文件名;key[in]:键-值中的键;symbol[in]:处于键-值之间的的符号,
         该符号必须具备将键-值区别开的能力,即键,值中不能包含该字符;value[in]:键-值中的值
 *输   出:key
 *返回 值:成功返回0,如果返回-1
 *说  明:
 *************************************************************
 */
int conf_file_get_value_by_key(const char *file,const  char *key,const char symbol, char *value);

#endif 

3, test.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<unistd.h>
#include"conf_file.h"

static void Fork(){
    pid_t temp_pid;
    temp_pid = fork();
    if(temp_pid < 0){
        exit(-1);
    }else if(temp_pid > 0){
        exit(0);
    }
}


int main(int argc, char *argv[]){
    char value[256];
    if(argc > 2) return 0; 
    if(argc == 2){
        if(0 == strcmp("-f", argv[1])){
            Fork();
        }else return -1;
    }
    //

    // if(argv[1]){
    //     if(argv[2]){
    //         conf_file_set_value_by_key("test.ini", argv[1], ':', argv[2]);
    //     }else{
    //         conf_file_set_value_by_key("test.ini", "ip", ':', argv[1]);
    //     }
    // }else{  
    //     conf_file_set_value_by_key("test.ini", "ip", ':', "2345");
    // }
    if(argv[1]){
        conf_file_get_value_by_key("test.ini", argv[1], ':', value);
    }else{  
        conf_file_get_value_by_key("test.ini", "ip", ':', value);
    }
    printf("strlen(value):%lu value:%s\n",strlen(value),value);
    while(1){
        sleep(5);
        printf("%s %s %d\n",__FILE__, __func__, __LINE__);
    }
    return 0;
}

4,Makefile


TARGET=test
OBJECT=test.c conf_file.c
$(TARGET):$(OBJECT)
	gcc -g -Wall $(OBJECT) -o $(TARGET)
clean:
	rm $(TARGET)


5,test.ini

ip:2345
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 读写ini文件在Linux环境下可以使用多种方式实现。其中比较常用的有通过bash脚本和使用编程语言C语言实现。 在bash脚本中,我们可以使用命令行工具如sed、awk、grep等来读写ini文件。比如,我们可以通过grep命令来查找ini文件中的特定配置项,然后使用sed命令来修改或添加配置项的值。同时,可以使用echo命令将配置项写入ini文件中。 另外,我们还可以使用C语言读写ini文件。对于读取ini文件,可以使用标准C库中的文件操作函数,如fopen、fread等来实现。在写入ini文件时,可以使用fprintf函数将配置项写入文件中。 总之,就读写ini文件而言,可以根据具体的需求和环境选择合适的方式实现。无论是使用bash脚本还是编程语言,都可以灵活地读取和修改ini文件中的配置项。 ### 回答2: 在Linux环境中读写INI文件,可以使用C语言编写程序来实现。 首先,需要使用标准C库中的文件操作函数来打开和读取INI文件。可以使用fopen()函数打开INI文件,并使用fgets()函数逐行读取文件内容。对于每一行内容,使用字符串处理函数来解析出键值对。 同时,可以定义结构体来存储键值对的信息。结构体可以包含两个成员,一个成员用于存储键的名称,另一个成员用于存储键对应的值。 读取INI文件的过程中,可以使用字符串处理函数来解析每一行的内容。可以使用strtok()函数将每一行内容按照等号 "=" 分割成键和值。然后可以使用strcpy()函数将键和值的内容分别复制给对应的结构体成员。 读取完INI文件内容后,可以关闭文件,释放资源。 对于写INI文件,可以使用标准C库中的文件操作函数打开文件,并使用fprintf()函数向文件中写入键值对信息。可以按照INI文件的格式,将键和值以等号 "="分割,并在写入时添加对应的注释信息。 写入INI文件完成后,可以关闭文件,释放资源。 需要注意的是,读写INI文件需确保文件的编码格式为ASCII或UTF-8,以免出现乱码问题。同时,还应注意处理异常情况,如文件不存在或读写失败等,以保证程序的健壮性。 以上是使用C语言Linux环境中读写INI文件的基本过程。具体的实现方式可根据实际需求和个人编程经验进行调整和优化。 ### 回答3: 在Linux环境下,可以使用C语言读写ini配置文件。首先需要创建一个ini配置文件,它是一种文本文件,通常以.ini为扩展名。ini配置文件的格式是键值对的形式,由多个节(section)组成,每个节中可以包含多个键(key)和对应的值(value)。 读取ini配置文件可以通过使用C语言中的标准库函数来实现。首先使用fopen函数打开ini配置文件,并以只读模式("r")打开。然后通过fgets函数逐行读取文件内容,判断每一行是否为节或键值对。如果是节,则可以将节名存储起来,如果是键值对,则可以将键和值分别存储起来。 写入ini配置文件可以通过使用C语言中的标准库函数来实现。首先使用fopen函数打开ini配置文件,并以写入模式("w")打开。然后将要写入的节、键和值格式化成字符串,并通过fprintf函数将其写入文件中。需要注意的是,在写入之前可能需要先将原有的ini配置文件内容备份,以免丢失。 除了使用标准库函数之外,也可以使用开源的第三方库,如libini等,来更方便地读写ini配置文件。这些库提供了更简单的接口和函数,能够更便捷地读取和修改ini文件。在使用这些库时,需要先安装相应的库文件,并在编译时链接库文件。 总之,通过C语言可以在Linux环境下读写ini配置文件。读取可以使用标准库函数或第三方库函数,写入则可以使用标准库函数或第三方库函数。具体的实现方式可以根据实际需求和情况选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值