用C實(shí)現(xiàn)添加和讀取配置文件函數(shù)
更新時(shí)間:2013年05月28日 16:48:21 作者:
本篇文章是對(duì)用C語言實(shí)現(xiàn)添加和讀取配置文件函數(shù)的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
發(fā)現(xiàn)讀取配置文件, 還是用得比較多的. 網(wǎng)上搜了下, 有不少的代碼范例了.
不過一般實(shí)現(xiàn)的函數(shù)需要傳遞的參數(shù)都有配置文件的路徑.
個(gè)人認(rèn)為在某些情況下參數(shù)傳入 流 重用性更大一點(diǎn).
本想基于流的參數(shù)將 讀取, 添加, 刪除, 修改 配置文件的函數(shù)全部實(shí)現(xiàn). 但發(fā)現(xiàn)
刪除 , 修改 需要重新打開流, 單純傳入一個(gè)流參數(shù)不能方便實(shí)現(xiàn).
以下是讀取, 添加 配置的函數(shù)實(shí)現(xiàn).
"oper_config.h"
#ifndef OPER_CONFIG_H_
#define OPER_CONFIG_H_
#define MAX_LINE_LEN 210
char *read_config(FILE *fp, char *key);
int add_config(FILE *fp, char *key, char *value);
#endif
"oper_config.c"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "oper_config.h"
static int check_key(char *line, char *key);
static char *get_value(char *line);
// fp 需要以讀的方式得到
char *
read_config(FILE *fp, char *key)
{
char line[MAX_LINE_LEN] = {'\0'};
char *value = NULL;
int ret;
while(fgets( line, sizeof(line), fp) != NULL)
{
ret = check_key(line, key);
if(ret == -1)
{
continue;
}
else
{
value = get_value(line);
if(value == NULL)
{
del_config(fp, key);
return NULL;
}
else
{
return value;
}
}
}/* while */
return NULL;
}
static int
check_key(char *line, char *key)
{
char *k_start, *k_end; // 指示 key 在 line 中的起始和結(jié)束位置
int line_len;
line_len = strlen(line);
if(line_len < 3)
{
return(-1);
}
else
{
k_start = &line[0];
while(((*k_start == ' ') || (*k_start == '\t'))
&& ( k_start <= &line[line_len - 1]))
{
k_start ++;
}
if(*k_start == '#')
{
return(-1);
}
k_end = strchr(line, '=');
if(k_end == NULL)
{
return(-1);
}
k_end --;
while(((*k_end == ' ') || (*k_end == '\t'))
&& (k_end >= k_start))
{
k_end --;
}
if((*k_end == ' ') || (*k_end == '\t'))
{
return(-1);
}
if(strncmp(key, k_start, k_end-k_start + 1) != 0)
{
return(-1);
}
}
return(0);
}/* check_key() */
static char*
get_value(char *line)
{
char *v_start, *v_end; // 指示 value 在 line 中的起始和結(jié)束位置
char *value = NULL;
int line_len;
int val_len;
line_len = strlen(line);
v_start = strchr(line, '='); // 已經(jīng)在 check_key 中檢驗(yàn)過'='的存在
v_start ++;
while(((*v_start == ' ') || (*v_start == '\t'))
&& (v_start <= &line[line_len - 1]))
{
v_start ++;
}
v_end = &line[line_len - 1];
if(((*v_end == ' ') || (*v_end == '\t')
|| (*v_end == '\n')
|| (*v_end == '\r'))
&& (v_end > v_start))
{
v_end --;
}
if((*v_end == ' ') || (*v_end == '\t')
|| (*v_end == '\n')
|| (*v_end == '\r'))
{
return NULL;
}
val_len = v_end - v_start + 1;
value = (char *)malloc((val_len + 1) * sizeof(char));
if(value == NULL)
{
printf("malloc failed.\n");
return NULL;
}
strncpy(value, v_start, val_len);
value[val_len] = '\0';
return value;
}/* get_value() */
// fp 需要以添加的方式得到
int
add_config(FILE *fp, char *key, char *value)
{
char *line = NULL;
int key_len;
int val_len;
key_len = strlen(key);
val_len = strlen(value);
if( (fp == NULL) || (key == NULL) || (value == NULL))
{
return(-1);
}
line = (char *)malloc((key_len + val_len + 5) * sizeof(char));
if(line == NULL)
{
printf("malloc failed.\n");
return(-1);
}
else
{
strncpy(line, key, key_len);
line[key_len] = ' ';
line[key_len + 1] = '=';
line[key_len + 2] = ' ';
line[key_len + 3] = '\0';
strncat(line, value, val_len);
line[key_len + val_len + 3] = '\n';
line[key_len + val_len + 4] = '\0';
if(fputs(line, fp) == EOF)
{
return(-1);
}
}
free(line);
return(0);
}/* add_config() */
說明:
1) 配置文件的數(shù)據(jù)格式 key = value
2) 支持 '#' 開頭注釋
3) key, value 前后可有空格, tab.
不過一般實(shí)現(xiàn)的函數(shù)需要傳遞的參數(shù)都有配置文件的路徑.
個(gè)人認(rèn)為在某些情況下參數(shù)傳入 流 重用性更大一點(diǎn).
本想基于流的參數(shù)將 讀取, 添加, 刪除, 修改 配置文件的函數(shù)全部實(shí)現(xiàn). 但發(fā)現(xiàn)
刪除 , 修改 需要重新打開流, 單純傳入一個(gè)流參數(shù)不能方便實(shí)現(xiàn).
以下是讀取, 添加 配置的函數(shù)實(shí)現(xiàn).
"oper_config.h"
復(fù)制代碼 代碼如下:
#ifndef OPER_CONFIG_H_
#define OPER_CONFIG_H_
#define MAX_LINE_LEN 210
char *read_config(FILE *fp, char *key);
int add_config(FILE *fp, char *key, char *value);
#endif
"oper_config.c"
復(fù)制代碼 代碼如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "oper_config.h"
static int check_key(char *line, char *key);
static char *get_value(char *line);
// fp 需要以讀的方式得到
char *
read_config(FILE *fp, char *key)
{
char line[MAX_LINE_LEN] = {'\0'};
char *value = NULL;
int ret;
while(fgets( line, sizeof(line), fp) != NULL)
{
ret = check_key(line, key);
if(ret == -1)
{
continue;
}
else
{
value = get_value(line);
if(value == NULL)
{
del_config(fp, key);
return NULL;
}
else
{
return value;
}
}
}/* while */
return NULL;
}
static int
check_key(char *line, char *key)
{
char *k_start, *k_end; // 指示 key 在 line 中的起始和結(jié)束位置
int line_len;
line_len = strlen(line);
if(line_len < 3)
{
return(-1);
}
else
{
k_start = &line[0];
while(((*k_start == ' ') || (*k_start == '\t'))
&& ( k_start <= &line[line_len - 1]))
{
k_start ++;
}
if(*k_start == '#')
{
return(-1);
}
k_end = strchr(line, '=');
if(k_end == NULL)
{
return(-1);
}
k_end --;
while(((*k_end == ' ') || (*k_end == '\t'))
&& (k_end >= k_start))
{
k_end --;
}
if((*k_end == ' ') || (*k_end == '\t'))
{
return(-1);
}
if(strncmp(key, k_start, k_end-k_start + 1) != 0)
{
return(-1);
}
}
return(0);
}/* check_key() */
static char*
get_value(char *line)
{
char *v_start, *v_end; // 指示 value 在 line 中的起始和結(jié)束位置
char *value = NULL;
int line_len;
int val_len;
line_len = strlen(line);
v_start = strchr(line, '='); // 已經(jīng)在 check_key 中檢驗(yàn)過'='的存在
v_start ++;
while(((*v_start == ' ') || (*v_start == '\t'))
&& (v_start <= &line[line_len - 1]))
{
v_start ++;
}
v_end = &line[line_len - 1];
if(((*v_end == ' ') || (*v_end == '\t')
|| (*v_end == '\n')
|| (*v_end == '\r'))
&& (v_end > v_start))
{
v_end --;
}
if((*v_end == ' ') || (*v_end == '\t')
|| (*v_end == '\n')
|| (*v_end == '\r'))
{
return NULL;
}
val_len = v_end - v_start + 1;
value = (char *)malloc((val_len + 1) * sizeof(char));
if(value == NULL)
{
printf("malloc failed.\n");
return NULL;
}
strncpy(value, v_start, val_len);
value[val_len] = '\0';
return value;
}/* get_value() */
// fp 需要以添加的方式得到
int
add_config(FILE *fp, char *key, char *value)
{
char *line = NULL;
int key_len;
int val_len;
key_len = strlen(key);
val_len = strlen(value);
if( (fp == NULL) || (key == NULL) || (value == NULL))
{
return(-1);
}
line = (char *)malloc((key_len + val_len + 5) * sizeof(char));
if(line == NULL)
{
printf("malloc failed.\n");
return(-1);
}
else
{
strncpy(line, key, key_len);
line[key_len] = ' ';
line[key_len + 1] = '=';
line[key_len + 2] = ' ';
line[key_len + 3] = '\0';
strncat(line, value, val_len);
line[key_len + val_len + 3] = '\n';
line[key_len + val_len + 4] = '\0';
if(fputs(line, fp) == EOF)
{
return(-1);
}
}
free(line);
return(0);
}/* add_config() */
說明:
1) 配置文件的數(shù)據(jù)格式 key = value
2) 支持 '#' 開頭注釋
3) key, value 前后可有空格, tab.
相關(guān)文章
C語言實(shí)例問題探究字符串函數(shù)的應(yīng)用
字符串函數(shù)(String processing function)也叫字符串處理函數(shù),指的是編程語言中用來進(jìn)行字符串處理的函數(shù),如C,pascal,Visual以及LotusScript中進(jìn)行字符串拷貝,計(jì)算長度,字符查找等的函數(shù)2022-04-04C/C++之long int與long long的區(qū)別及說明
這篇文章主要介紹了C/C++之long int與long long的區(qū)別及說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08C++數(shù)據(jù)結(jié)構(gòu)的隊(duì)列詳解
這篇文章主要為大家介紹了C++數(shù)據(jù)結(jié)構(gòu)的隊(duì)列,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2021-11-11