一,
实现了一个灵活的读取或设置配置文件中的键-值中的值的功能
使用规则如下
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