C 添加, 读取配置文件 函数

发现读取配置文件, 还是用得比较多的. 网上搜了下, 有不少的代码范例了.

不过一般实现的函数需要传递的参数都有配置文件的路径.

个人认为在某些情况下参数传入 流 重用性更大一点.

本想基于流的参数将 读取, 添加, 删除, 修改 配置文件的函数全部实现. 但发现

删除 , 修改 需要重新打开流, 单纯传入一个流参数不能方便实现.

以下是读取, 添加 配置的函数实现.


"oper_config.h"

/*
 * author: dengzhaoqun
 * date	 : 2011/07/23
 */

#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"

/*
 * author: dengzhaoqun
 * date  : 2011/07/22
 */

#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.


基于路径的实现, 请参考 http://www.linuxidc.com/Linux/2011-03/33712.htm

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
纯c读写ini配置文件 用c/c++读写ini配置文件有不少第三方的开源库,如iniparser、libini、rwini、UltraLightINIParser等,但都不理想,往往代码较大、功能较弱、 接口使用不方便。尤其在大小写处理、前后空格、各种注释、跨平台换行符支持、带引号字符串处理、无section操作、原格式保持等方面存在问题。 现将本人精心制作的ini读写程序源码奉献给大家,纯c编写,简洁好用。支持windows和linux。 主要特点: 1、支持;和#注释符号,支持行尾注释。 2、支持带引号'或"成对匹配的字符串,提取时自动去引号。引号中可带其它引号或;#注释符。 3、支持无section或空section(名称为空)。 4、支持10、16、8进制数,0x开头为16进制数,0开头为8进制。 5、支持section、key或=号前后带空格。 6、支持\n、\r、\r\n或\n\r换行格式。 7、不区分section、key大小写,但写入时以新串为准,并保持其大小写。 8、新增数据时,若section存在则在该节最后一个有效数据后添加,否则在文件尾部添加。 9、支持指定key所在整行删除,即删除该键值,包括注释。 10、可自动跳过格式错误行,修改时仍然保留。 11、修改时保留原注释:包括整行注释、行尾注释(包括前面空格)。 12、修改时保留原空行。以上三点主要是尽量保留原格式。 不足之处: 1、不支持单key多value(逗号分割),只能一次性提取后自行处理。 2、不支持同名重复section和key。(重复section可视为错误,重复key则可能造成分歧) 3、不能提取所有section或key名称。 使用只需两个文件inirw.h、inirw.c,另有测试程序和工程文件,支持windows和linux。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值