用C實(shí)現(xiàn)添加和讀取配置文件函數(shù)
發(fā)現(xiàn)讀取配置文件, 還是用得比較多的. 網(wǎng)上搜了下, 有不少的代碼范例了.
不過(guò)一般實(shí)現(xiàn)的函數(shù)需要傳遞的參數(shù)都有配置文件的路徑.
個(gè)人認(rèn)為在某些情況下參數(shù)傳入 流 重用性更大一點(diǎn).
本想基于流的參數(shù)將 讀取, 添加, 刪除, 修改 配置文件的函數(shù)全部實(shí)現(xiàn). 但發(fā)現(xiàn)
刪除 , 修改 需要重新打開(kāi)流, 單純傳入一個(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)過(guò)'='的存在
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() */
說(shuō)明:
1) 配置文件的數(shù)據(jù)格式 key = value
2) 支持 '#' 開(kāi)頭注釋
3) key, value 前后可有空格, tab.
上一篇:使用C語(yǔ)言遞歸與非遞歸實(shí)現(xiàn)字符串反轉(zhuǎn)函數(shù)char *reverse(char *str)的方法
欄 目:C語(yǔ)言
下一篇:如何判斷一個(gè)整數(shù)的二進(jìn)制中有多少個(gè)1
本文標(biāo)題:用C實(shí)現(xiàn)添加和讀取配置文件函數(shù)
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/4448.html
您可能感興趣的文章
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用函數(shù)刪除字符
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段函數(shù)
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段函數(shù)
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求階乘
- 01-10數(shù)據(jù)結(jié)構(gòu)課程設(shè)計(jì)-用棧實(shí)現(xiàn)表達(dá)式求值的方法詳解
- 01-10使用OpenGL實(shí)現(xiàn)3D立體顯示的程序代碼
- 01-10HDOJ 1443 約瑟夫環(huán)的最新應(yīng)用分析詳解
- 01-10用貪心法求解背包問(wèn)題的解決方法
- 01-10求斐波那契(Fibonacci)數(shù)列通項(xiàng)的七種實(shí)現(xiàn)方法


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹(shù)的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒(méi)有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-10C#中split用法實(shí)例總結(jié)
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開(kāi)原生自帶讀寫NTFS功能(圖文
- 01-10SublimeText編譯C開(kāi)發(fā)環(huán)境設(shè)置
- 04-02jquery與jsp,用jquery


