用C實現添加和讀取設定檔函數

來源:互聯網
上載者:User

發現讀取設定檔, 還是用得比較多的. 網上搜了下, 有不少的代碼範例了.
不過一般實現的函數需要傳遞的參數都有設定檔的路徑.
個人認為在某些情況下參數傳入 流 重用性更大一點.
本想基於流的參數將 讀取, 添加, 刪除, 修改 設定檔的函數全部實現. 但發現
刪除 , 修改 需要重新開啟流, 單純傳入一個流參數不能方便實現.
以下是讀取, 添加 配置的函數實現.
"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 中的起始和結束位置
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 中的起始和結束位置
char *value = NULL;
int line_len;
int val_len;
line_len = strlen(line);
v_start = strchr(line, '='); // 已經在 check_key 中檢驗過'='的存在
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) 設定檔的資料格式 key = value
2) 支援 '#' 開頭注釋
3) key, value 前後可有空格, tab.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.