配置文件读写

有一个config.txt文件内容如下:

要求:输出有效信息,输入:左边的属性(key),屏幕能输出右边的value

/*
  config.h
*/
#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

struct Hero
{
	char key[64];
	char value[64];
};


//获取有效行数
int getFileLine(char* filename);

//判断当前行是否有效
int isValidLine(char* str);

//解析文件
void parseFile(char* filename,struct Hero** hero,int line);

//根据索引值获取 实值
char* toValue(char* str,struct Hero* hero,int line);

//释放信息
void freeSpace(struct Hero* info);

 

/*
   config.c
*/

#include"config.h"
//获取有效行数 + 解析文件
int getFileLine(char* filename)
{
	int line = 0;
	
	char buff[1024] = {0};
	

	FILE* f_read = fopen(filename,"r");
	if(f_read == NULL)
	{
		return -1;
	}
	while(!feof(f_read))
	{
		fgets(buff,1024,f_read);
		
		if(isValidLine(buff))
		{
			line ++;
		}
	}
	
	
	return line;
}

//判断当前行是否有效
int isValidLine(char* str)
{
	if(str[0] == '\0' || str[0] == ' ' || strchr(str,':') == NULL)
	{
		return 0;
	}
	return 1;
}

//解析文件
void parseFile(char* filename,struct Hero** hero,int line)
{
	
	int index = 0;
	char buff[1024] = { 0 };
	
	//char* pos = strchr(buff,':'); //pos 代表冒号所在位置
	char* pos = (char*)malloc(sizeof(char));
	struct Hero* info = (struct Hero*)malloc(sizeof(struct Hero) * line);
	FILE* f_read = fopen(filename,"r");
	if(f_read == NULL)
	{
		return;
	}
	while(fgets(buff,1024,f_read)!=NULL)
	{
		//fgets(buff,1024,f_read);
		//有效信息才会被解析
		if(isValidLine(buff))
		{
			//清空操作
			
			memset(info[index].key,0,64);//将key域清0
			memset(info[index].value,0,64);
			
			pos = strchr(buff,':'); //pos 代表冒号所在位置
			strncpy(info[index].key,buff,pos - buff);
			
			strncpy(info[index].value,pos + 1,strlen(pos + 1) - 1);//减1是因为每行以'\n'结尾,打印的时候会多输出一行换行

			printf("key = %s",info[index].key);
			printf("value = %s\n",info[index].value);
			index ++;
		}
		memset(buff,0,1024);
	}
	*hero = info;

}

//根据索引值获取 实值
char* toValue(char* str,struct Hero* hero,int line)
{
	int i;
	for(i = 0;i < line; i++)
	{
		if(strcmp(str,hero[i].key) == 0)
		{
			return hero[i].value ;
		}
	}
	return NULL;
}

//释放信息
void freeSpace(struct Hero* info)
{
	if(info != NULL)
	{
		free(info);
		info = NULL;
	}

}
/*
   test.c
*/

#include<stdio.h>
#include<string.h>
#include"config.h"

void test01()
{
	int line;
	char* filepath = "./config.txt";
	struct Hero* hero = NULL;
	line = getFileLine(filepath);

	printf("有效行数为:%d\n",line);
	//测试 根据key 访问 value
	parseFile(filepath,&hero,line);
	printf("heroId = %s\n",toValue("heroId",hero,line));
	printf("heroName = %s\n",toValue("heroName",hero,line));
	printf("heroAtk = %s\n",toValue("heroAtk",hero,line));
	printf("heroDef = %s\n",toValue("heroDef",hero,line));
	printf("heroInfo = %s\n",toValue("heroInfo",hero,line));
	
}


int main()
{
	test01();

	return 0;
}

 

 结果如果读出来中文是乱码,可以检查下读取的文件是不是ANSI格式。

 

 

  • 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、付费专栏及课程。

余额充值