news 2026/6/15 0:31:15

配置文件 ini文件的使用.(c 解析代码)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
配置文件 ini文件的使用.(c 解析代码)

author: hjjdebug
date: 2026年 01月 14日 星期三 19:58:22 CST
descrip: 配置文件 ini文件的使用.(c 解析代码)


文章目录

  • 1. 什么是ini 文件?
  • 2. 把ini 文件读入内存.
  • 3. ini 文件的使用.
  • 4. 源码及测试用例.
    • 4.1 ini解析文件
    • 4.2 ini解析头文件
    • 4.3 ini 测试代码
    • 4.4 ini 测试文件
    • 4.5 Makefile

用户与计算机交互, 直接靠键盘从命令行输入只能输入一行信息,
怎样更有效的与计算机交互?
通过文件.
但是文件的格式必须要符合一定的规则, 计算机才能按规则解析.
ini 文件是规则定义非常简单的文件格式.

1. 什么是ini 文件?

ini -> initialization”初始化的缩写,
ini 文件,是一种纯文本格式,

其核心结构由节(Section)、键(Key)和值(Value)组成.
其中节用方括号[ ]标识(例如[Section1]),
键值对采用键=值的形式, 一行一个
例如:
port=4
host=192.168.6.1

由于其简单实用性, 许多应用程序仍使用它来保存用户设置
或输出程序状态.
对于复杂场景,还可以采用 “JSON”,“YAML”,"XML"等格式.

2. 把ini 文件读入内存.

计算机擅长的是处理特定的结构变量数据.
把ini 文件进行解析, 分析出其结构数据并加以存储, 这就是ini 文件加载的过程
代码定义了一个IniItem 结构,
把用户在文件中定义的条目, 一行行的读取过来, 并分析用户定义,section,key=value信息
存储到 item 项中, 构成数组

3. ini 文件的使用.

对结构数据的访问需要通过接口来进行, 当然你需要给出一个数据handle,
类似于c++编程中this指针的意思, 也就是它对应了一块内存. 给了这个内存地址,就能找到所有数据.
然后再给出限定条件,例如节名,键名, 就可以拿到对应的值.
接口定义如下:
const char* ini_get(IniFile* ini, const char* section, const char* key);

ini 就是handle
有了handle,如果愿意,还可以继续写其它接口函数.
例如可以打印所有的节名,键名,甚至键值对等.
不过我们一般也就只需要ini_get 就可以了, 它最常用.

4. 源码及测试用例.

不足百行代码,轻量级,简单实用! 不推荐用那些重量级代码,大部分功能是用不到的.

4.1 ini解析文件

$ cat ini_parser.c#include<stdio.h>#include<stdlib.h>#include<string.h>#include"ini_parser.h"//读取文件, 把行配置信息存储到条目中.IniFile*ini_load(constchar*filename){FILE*file=fopen(filename,"r");if(!file)returnNULL;IniFile*ini=(IniFile*)malloc(sizeof(IniFile));ini->items=(IniItem*)malloc(sizeof(IniItem)*16);//初始化分配16个条目空间ini->count=0;ini->capacity=16;charline[MAX_LINE_LENGTH];charsec_name[MAX_KEY_LENGTH]="";char*p;while(fgets(line,sizeof(line),file)){// 去除换行符line[strcspn(line,"\r\n")]=0;// 跳过空行和注释if(strlen(line)==0||line[0]==';'||line[0]=='#')continue;// 解析节名 [section]//跳过行首白空格p=line;while(*p==' '||*p=='\t')p++;if(*p=='['){char*end=strrchr(p,']');if(end){*end='\0';strcpy(sec_name,p+1);}continue;}// 解析键值对 key=value, 保留item 项char*equals=strchr(line,'=');if(equals&&strlen(sec_name)>0){*equals='\0';char*key=line;char*value=equals+1;// 去除首尾空格while(*key==' ')key++;char*key_end=key+strlen(key)-1;while(key_end>key&&*key_end==' ')key_end--;*(key_end+1)='\0';while(*value==' ')value++;char*value_end=value+strlen(value)-1;while(value_end>value&&*value_end==' ')value_end--;*(value_end+1)='\0';if(ini->count>=ini->capacity){ini->capacity*=2;ini->items=(IniItem*)realloc(ini->items,sizeof(IniItem)*ini->capacity);}IniItem*item=&ini->items[ini->count++];strcpy(item->section,sec_name);strcpy(item->key,key);strcpy(item->value,value);}}fclose(file);returnini;}voidini_free(IniFile*ini){if(ini){free(ini->items);free(ini);}}constchar*ini_get(IniFile*ini,constchar*section,constchar*key){for(inti=0;i<ini->count;i++){if(strcmp(ini->items[i].section,section)==0&&strcmp(ini->items[i].key,key)==0){returnini->items[i].value;}}returnNULL;}

4.2 ini解析头文件

$ cat ini_parser.h#ifndefINI_PARSER_H#defineINI_PARSER_H//常数定义, 内存写死,虽然浪费点内存,但使用简单.#defineMAX_LINE_LENGTH1024#defineMAX_KEY_LENGTH256#defineMAX_VALUE_LENGTH256//ini 条目结构体, 定义节名,键名和值// 本来更好的结构是1个节下带若干个键值对,// 这里就简单点,每一项都带上节名typedefstruct{charsection[MAX_KEY_LENGTH];//节名charkey[MAX_KEY_LENGTH];//键名charvalue[MAX_VALUE_LENGTH];//键值}IniItem;//由iniFile 可以获取所有的IniItem.typedefstruct{IniItem*items;//条目数组指针intcount;//条目数量intcapacity;//分配的条目容量大小}IniFile;IniFile*ini_load(constchar*filename);voidini_free(IniFile*ini);//根据节名,键名获取对应的值constchar*ini_get(IniFile*ini,constchar*section,constchar*key);#endif

4.3 ini 测试代码

$ cat main.c#include<stdio.h>#include"ini_parser.h"intmain(){IniFile*ini=ini_load("config.ini");if(!ini){printf("无法加载配置文件\n");return1;}constchar*db_host=ini_get(ini,"database","host");constchar*db_port=ini_get(ini,"database","port");constchar*app_name=ini_get(ini,"app","name");printf("数据库主机: %s\n",db_host?db_host:"未设置");printf("数据库端口: %s\n",db_port?db_port:"未设置");printf("应用名称: %s\n",app_name?app_name:"未设置");ini_free(ini);return0;}

4.4 ini 测试文件

与main.c 的调用相呼应,就自己写一个,如下

$ cat config.ini[database]host=192.168.6.1;port=8080[app]name=test

4.5 Makefile

$ cat Makefile CC=gcc CFLAGS=-g-Wall-Wextra-std=c99 TARGET=ini_parser SRCS=main.c ini_parser.c OBJS=$(SRCS:.c=.o)all:$(TARGET)$(TARGET):$(OBJS)$(CC)$(CFLAGS)-o $(TARGET)$(OBJS)%.o:%.c $(CC)$(CFLAGS)-c $<-o $@ clean:rm-f $(OBJS)$(TARGET).PHONY:all clean

执行结果:
./ini_parser
数据库主机: 192.168.6.1;
数据库端口: 8080
应用名称: test

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/13 21:54:33

终极教育资源下载工具:三步快速获取智慧教育平台内容

终极教育资源下载工具&#xff1a;三步快速获取智慧教育平台内容 【免费下载链接】knowledge-grab knowledge-grab 是一个基于 Tauri 和 Vue 3 构建的桌面应用程序&#xff0c;方便用户从 国家中小学智慧教育平台 (basic.smartedu.cn) 下载各类教育资源。 项目地址: https://…

作者头像 李华
网站建设 2026/6/13 18:56:10

10分钟掌握PoeCharm:流放之路BD构建实战指南

10分钟掌握PoeCharm&#xff1a;流放之路BD构建实战指南 【免费下载链接】PoeCharm Path of Building Chinese version 项目地址: https://gitcode.com/gh_mirrors/po/PoeCharm PoeCharm是《流放之路》Path of Building工具的完整汉化版本&#xff0c;专为中文玩家打造的…

作者头像 李华
网站建设 2026/6/13 17:25:12

VRX仿真平台:打造智能无人船开发的终极利器

VRX仿真平台&#xff1a;打造智能无人船开发的终极利器 【免费下载链接】vrx Virtual RobotX (VRX) resources. 项目地址: https://gitcode.com/gh_mirrors/vr/vrx 在海洋机器人技术飞速发展的今天&#xff0c;Virtual RobotX&#xff08;VRX&#xff09;仿真平台以其专…

作者头像 李华
网站建设 2026/6/14 0:46:56

OpenCV文档扫描仪优化指南:提升小文本识别率的实用方法

OpenCV文档扫描仪优化指南&#xff1a;提升小文本识别率的实用方法 1. 背景与挑战&#xff1a;传统文档扫描在小文本场景下的局限性 随着数字化办公的普及&#xff0c;基于图像处理的智能文档扫描技术已成为日常工作中不可或缺的一环。OpenCV 提供了一套无需深度学习模型、轻…

作者头像 李华
网站建设 2026/6/13 9:32:36

VirtualBrowser终极方案:3步完美解决浏览器指纹追踪难题

VirtualBrowser终极方案&#xff1a;3步完美解决浏览器指纹追踪难题 【免费下载链接】VirtualBrowser Free anti fingerprint browser, 指纹浏览器, 隐私浏览器, 免费的web3空投专用指纹浏览器 项目地址: https://gitcode.com/gh_mirrors/vi/VirtualBrowser 想象一下&am…

作者头像 李华
网站建设 2026/6/13 12:55:09

5个必学技巧:BiliTools跨平台下载工具完整使用指南

5个必学技巧&#xff1a;BiliTools跨平台下载工具完整使用指南 【免费下载链接】BiliTools A cross-platform bilibili toolbox. 跨平台哔哩哔哩工具箱&#xff0c;支持视频、音乐、番剧、课程下载……持续更新 项目地址: https://gitcode.com/GitHub_Trending/bilit/BiliToo…

作者头像 李华