(1)配置文件的读写

cfg_op.h:

#pragma once
#define _CRT_NONSTDC_NO_WARNINGS  //防止使用C语言函数报出不安全的错误
#ifndef _CFG_OP_H_
#define _CFG_OP_H_
#ifdef __cplusplus
extern "C"

int cfgWrite(char * fileName,char* key,char* value);
int cfgRead(char* fileName, char* key, char* value);

#endif
#endif // !CFG_OP_H

cfg_op.cpp

#include"cfg_op.h"
#include<iostream>
using namespace std;
#define maxline 2048
int cfgWrite(char * fileName, char* key, char* value) {  //先把文件内容全部读入内存中,在进行数据写入
	FILE *f;
	int ret = 0, flag = 0;
	char buf[maxline];
	char filebuf[1024 * 8] = { 0 };
	char* ptem = NULL;
	char* pbegin = NULL, *pend = NULL;
	if (fileName == NULL || key == NULL || value == NULL) {
		ret = -2;
		goto End;
	}
	f = fopen(fileName, "r+");
	if (f == NULL) {
		ret = -1;
		cout << "打开文件失败!" << endl;
	}
	if (f == NULL) {
		f = fopen(fileName, "w+t");
		if (f == NULL) {
			ret = -3;
			cout << "创建文件失败!" << endl;
			goto End;
		}
	}
	fseek(f, 0L, SEEK_END); //从文件开头跳至文件末尾
	int filelength = ftell(f);  //求文件长度
	fseek(f, 0L, SEEK_SET);  //跳至文件头部
	if (filelength > 1024 * 8) {
		cout << "文件内容长度超过8k,不支持!" << endl;
		goto End;
	}
	while (!feof(f))
	{
		memset(buf, 0, sizeof(buf));
		ptem = fgets(buf, maxline, f);
		if (ptem == NULL) break;
		ptem = strstr(buf, key);
		if (ptem == NULL) // 判断是否有key
		{
			strcat(filebuf, buf);
			continue;
		}
		else {
			sprintf(buf, "%s = %s\n", key, value); //替换读取的一行数据
			strcat(filebuf, buf);
			flag = 1; //判断是否是修改,还是直接写入新数据

		}
	}
	if (flag == 0) {
		fprintf(f, "%s = %s\n", key, value);
	}
	else
	{
		//修改 ,直接覆盖原文件,将filebuf中的数据写入新文件中,完成修改操作
		if (f != NULL) {
			fclose(f);
			f = NULL;//避免野指针
		}
		f = fopen(fileName, "w+t");
		if (f == NULL) {
			ret = -4;
			cout << "打开文件失败" << endl;
		}
		fputs(filebuf, f);
	}
End:
	if (f != NULL) {
		fclose(f);
	}
	return ret;
}
int cfgRead(char* fileName, char* key, char* value) {
	FILE *f;
	int ret = 0;
	char buf[maxline];
	char* ptem = NULL;
	char* pbegin,*pend;
	f = fopen(fileName, "r");
	if (f == NULL) {
		ret = -1;
		return ret;
	}
	while (!feof(f)) {
		memset(buf, 0, sizeof(buf));
		fgets(buf, maxline, f);
		ptem = strchr(buf, '=');
		if (ptem == NULL) continue;  //判断是否有等号
		ptem = strstr(buf, key);
		if (ptem == NULL) continue; // 判断是否有key
		ptem += strlen(key);
		ptem = strchr(ptem, '=');
		if (ptem == NULL) continue;
		ptem++;
		//获取开始点
		while (1) {
			if (*ptem == ' ') ptem++;
			else {
				if (*ptem == '\n')
				{
					ret = -2;
					goto End;
				}
				else {
					pbegin = ptem;
					break;
				}
			}
		}
		//获取结束点
		while (1) {
			if (*ptem == '\0' || *ptem == '\n') {
				break;
			}
		    ptem++;
		}
		pend = ptem;
		memcpy(value, pbegin, pend - pbegin);
		break;
	}
End:
	if (f != NULL) {
		fclose(f);
	}
	return ret;
}



main.cpp:

#include<iostream>
#include"cfg_op.h"
using namespace std;
#define MyCfG "C:/1.ini"
void print() {
	cout << "===================" << endl;
	cout << "1.读配置文件       " << endl;
	cout << "2.写配置文件       " << endl;
	cout << "0.退出             " << endl;
	cout << "===================" << endl;
}
int testWritecfg() {
	//写配置文件
	char key[1024] = { 0 };
	char value[1024] = { 0 };
	cout << "请输入key:";
	cin >> key;
	cout << "请输入value:";
	cin >> value;
	int ret=cfgWrite (MyCfG,key,value);
	if (ret != 0) {
		cout << "写配置文件错误!错误码为:" << ret << endl;
		return ret;
	}
	return 0;
}
int testReadcfg() {
	//读配置文件
	char key[1024] = { 0 };
	char value[1024] = { 0 };
	int len = 0;
	cout << "请输入key:";
	cin >> key;
	int ret = cfgRead(MyCfG, key, value);
	if (ret != 0) {
		cout << "读配置文件错误!错误码为:" << ret << endl;
		return ret;
	}
	cout<<"value值为:"<< value << endl;
	return 0;
}
void main() {
	int choose;
	for (;;) {
		print();
		cin >> choose;
		switch (choose) {
		case 1:testReadcfg(); break;
		case 2:testWritecfg(); break;
		case 0:exit(0);break;
		default:cout << "输入错误!" << endl;
		}
	}
}

这个读写ini文件程序有一个小bug,是由于strstr()函数导致的,只要输入的是已输入key的子串,那么不会创建新的key而是直接操作主串。








  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 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、付费专栏及课程。

余额充值