文章目录

一、了解什么是INI文件?二、INI文件的格式三、解析上述文件四、测试如下

一、了解什么是INI文件?

ini 文件是Initialization File的缩写,即初始化文件,这是用来配置应用软件以实现不同用户的要求。

二、INI文件的格式

INI文件由节、键、值组成。

一个简单的的INI文件例子如下:

[Setting]

INIT_FLAG=0;

VOLUME=1;

LANGUAGE=1;

如上例子,[Setting]就是节,=号左边的值是键,=号右边的是值。

三、解析上述文件

/*ini.h*/

#ifndef INI_H

#define INI_H

#include

#include

int GetIniKeyString(char *title,char *key,char *filename,char *buf);

int PutIniKeyString(char *title,char *key,char *val,char *filename);

#endif /*INI_H*/

/*ini.c*/

#include

#include

/*

* 函数名: GetIniKeyString

* 入口参数: title

* 配置文件中一组数据的标识

* key

* 这组数据中要读出的值的标识

* filename

* 要读取的文件路径

* 返回值: 找到需要查的值则返回正确结果 0

* 否则返回-1

*/

int GetIniKeyString(char *title,char *key,char *filename,char *buf)

{

FILE *fp;

int flag = 0;

char sTitle[64], *wTmp;

char sLine[1024];

sprintf(sTitle, "[%s]", title);

if(NULL == (fp = fopen(filename, "r"))) {

perror("fopen");

return -1;

}

while (NULL != fgets(sLine, 1024, fp)) {

// 这是注释行

if (0 == strncmp("//", sLine, 2)) continue;

if ('#' == sLine[0]) continue;

wTmp = strchr(sLine, '=');

if ((NULL != wTmp) && (1 == flag)) {

if (0 == strncmp(key, sLine, strlen(key))) { // 长度依文件读取的为准

sLine[strlen(sLine) - 1] = '\0';

fclose(fp);

while(*(wTmp + 1) == ' '){

wTmp++;

}

strcpy(buf,wTmp + 1);

return 0;

}

} else {

if (0 == strncmp(sTitle, sLine, strlen(sTitle))) { // 长度依文件读取的为准

flag = 1; // 找到标题位置

}

}

}

fclose(fp);

return -1;

}

/*

* 函数名: PutIniKeyString

* 入口参数: title

* 配置文件中一组数据的标识

* key

* 这组数据中要读出的值的标识

* val

* 更改后的值

* filename

* 要读取的文件路径

* 返回值: 成功返回 0

* 否则返回 -1

*/

int PutIniKeyString(char *title,char *key,char *val,char *filename)

{

FILE *fpr, *fpw;

int flag = 0;

char sLine[1024], sTitle[32], *wTmp;

sprintf(sTitle, "[%s]", title);

if (NULL == (fpr = fopen(filename, "r")))

return -1;// 读取原文件

sprintf(sLine, "%s.tmp", filename);

if (NULL == (fpw = fopen(sLine, "w")))

return -1;// 写入临时文件

while (NULL != fgets(sLine, 1024, fpr)) {

if (2 != flag) { // 如果找到要修改的那一行,则不会执行内部的操作

wTmp = strchr(sLine, '=');

if ((NULL != wTmp) && (1 == flag)) {

if (0 == strncmp(key, sLine, strlen(key))) { // 长度依文件读取的为准

flag = 2;// 更改值,方便写入文件

sprintf(wTmp + 1, " %s\n", val);

}

} else {

if (0 == strncmp(sTitle, sLine, strlen(sTitle))) { // 长度依文件读取的为准

flag = 1; // 找到标题位置

}

}

}

fputs(sLine, fpw); // 写入临时文件

}

fclose(fpr);

fclose(fpw);

sprintf(sLine, "%s.tmp", filename);

return rename(sLine, filename);// 将临时文件更新到原文件

}

上述两个函数是简单的解析函数,因为ini文件有很多种解析方式,根据不同的需求解析也不同

所以要进行修改

比如我的注释符号是 “ ;”,所以我需要修改 并且根据实际功能需求也可以进行进一步的封装

四、测试如下

ini样本文件

/*test.ini*/

[city]

beijing = hello-beijing

shanghai = hello-shanghai

#information

[study]

highschool = xxxx

university = yyyy

test.c程序

/*test.c*/

#include "ini.h"

#include

int main(int argc, char const *argv[])

{

char buff[100];

int ret;

ret = GetIniKeyString("city","beijing","./test.ini",buff);

printf("ret:%d,%s\n",ret,buff);

ret = GetIniKeyString("study","highschool","./test.ini",buff);

printf("ret:%d,%s\n",ret,buff);

ret = PutIniKeyString("study","highschool","zzzz","./test.ini");

printf("put ret:%d\n",ret);

ret = GetIniKeyString("study","highschool","./test.ini",buff);

printf("ret:%d,%s\n",ret,buff);

return 0;

}

} 结果如下:

ret:0,hello-beijing

ret:0,xxxx

put ret:0

ret:0,zzzz

相应的test.ini的study段highschool项变成了zzzz.

这里还要注意,section使用中文字符可能会无法识别!