使用好处:有些参数不用写死,也不用在编译时添加。免得每次修改参数修改代码或重新编译,直接使用配置文件即可。
类比windows下GetPrivateProfileString、GetPrivateProfileInt获取配置的API

1. 使用vs2019创建linux项目

1.1 测试的配置文件如下图

在这里插入图片描述

1.2 测试代码和结果如下图

在这里插入图片描述

2. 核心代码

2.1 ini.h

#ifndef __INI_H__
#define __INI_H__

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

#define BUF_SIZE 1024

int GetIniChar(char* section, char* key, char* buf, char* filename);
int GetIniInt(char* section, char* key, int defeat, char* filename);

#endif

2.2 ini.c

#include "ini.h"

// 获取char类型配置项
int GetIniChar(char* section, char* key, char* buf, char* filename)
{
	if (buf == NULL)
	{
		printf("buf is null\n");
		return -1;
	}
	memset(buf, 0, sizeof(buf));		// 清零

	if (section == NULL || key == NULL || filename == NULL)
	{
		printf("param is null\n");
		return -2;
	}
	char cSection[BUF_SIZE] = { 0 };			// 存放配置文件每行去除空格和注释的section
	sprintf(cSection, "[%s]", section);

	FILE* fp = NULL;							// 配置文件描述符
	if (NULL == (fp = fopen(filename, "r")))
	{
		printf("fopen err:%d [%s]\n", errno, strerror(errno));
		return -3;
	}
	
	char cBufFileLine[BUF_SIZE] = { 0 };		// 存放配置文件每行的实际数据
	int flag = 0;								// section标记
	while (NULL != fgets(cBufFileLine, BUF_SIZE, fp))
	{
		int i, j;									// 循环计数器
		
		// 去注释,去空格,去换行符
		char cBufLine[BUF_SIZE] = { 0 };			// 存放配置文件每行去除空格和注释的数据
		for (i = 0, j = 0; i < strlen(cBufFileLine); i++)
		{
			if (cBufFileLine[i] != ' ' && cBufFileLine[i] != '\t')
			{
				if (cBufFileLine[i] == ';' || cBufFileLine[i] == '\n')
				{
					cBufLine[j] = '\0';
					break;
				}
				cBufLine[j++] = cBufFileLine[i];
			}
		}

		char* cTmpString = NULL;					// 存放cBufLine中第一次出现字符=的位置及之后的字符串,用于提取value
		cTmpString = strchr(cBufLine, '=');	// 返回cBufFileLine中第一次出现字符=的位置,失败返回null
		if (cTmpString && flag)
		{
			// 获取key
			char cKey[BUF_SIZE] = { 0 };				// 存放配置文件每行去除空格和注释的key
			for (i = 0; i < strlen(cBufLine); i++)
			{
				cKey[i] = cBufLine[i];
				if (cBufLine[i] == '=')
				{
					cKey[i] = '\0';
					break;
				}
			}
			
			if (0 == strncmp(key, cKey, strlen(key)))
			{
				// 获取value
				char cValue[BUF_SIZE] = { 0 };				// 存放配置文件每行去除空格和注释的value
				for (i = 1; i < strlen(cTmpString); i++)
				{
					cValue[i - 1] = cTmpString[i];
				}
				
				fclose(fp);
				strcpy(buf, cValue);
				return 0;		// 成功
			}
		}
		else
		{
			if (flag && strchr(cBufLine, '[') && strchr(cBufLine, ']'))
			{
				fclose(fp);
				return  -4;		// 该section已经搜索完毕
			}
			if (0 == strncmp(cSection, cBufLine, strlen(cSection)))
			{
				flag = 1;
			}
		}

	}
	fclose(fp);
	return -5;	// 未找到配置项
}

// 获取int类型配置项
int GetIniInt(char* section, char* key, int defeat, char* filename)
{
	char cBuf[BUF_SIZE] = { 0 };
	if (0 == GetIniChar(section, key, cBuf, filename))
	{
		return atoi(cBuf);
	}
	return defeat;
}
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐