news 2026/5/30 21:09:50

配置文件 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/5/29 1:26:40

Qwen3-4B-Instruct与Phi-3对比:轻量级模型推理效率评测

Qwen3-4B-Instruct与Phi-3对比&#xff1a;轻量级模型推理效率评测 1. 背景与选型动机 在边缘计算、移动端部署和低延迟服务场景中&#xff0c;大语言模型的轻量化推理已成为工程落地的关键挑战。尽管千亿参数级别的模型在性能上表现卓越&#xff0c;但其高昂的算力需求限制了…

作者头像 李华
网站建设 2026/5/30 9:26:16

猫抓cat-catch终极使用指南:从零掌握资源嗅探核心技术

猫抓cat-catch终极使用指南&#xff1a;从零掌握资源嗅探核心技术 【免费下载链接】cat-catch 猫抓 chrome资源嗅探扩展 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 想要高效下载网页视频、音频和图片资源&#xff1f;猫抓cat-catch这款开源浏览器扩展…

作者头像 李华
网站建设 2026/5/28 19:22:21

TabDDPM:基于扩散模型的表格数据生成技术深度解析

TabDDPM&#xff1a;基于扩散模型的表格数据生成技术深度解析 【免费下载链接】tab-ddpm [ICML 2023] The official implementation of the paper "TabDDPM: Modelling Tabular Data with Diffusion Models" 项目地址: https://gitcode.com/gh_mirrors/ta/tab-ddpm…

作者头像 李华
网站建设 2026/5/30 8:00:23

BGE-Reranker-v2-m3应用实例:智能客服问答优化

BGE-Reranker-v2-m3应用实例&#xff1a;智能客服问答优化 1. 引言 1.1 智能客服中的检索挑战 在当前的智能客服系统中&#xff0c;基于向量相似度的检索技术&#xff08;如使用Sentence-BERT等模型生成嵌入&#xff09;已成为主流。然而&#xff0c;这类方法存在一个显著问…

作者头像 李华
网站建设 2026/5/28 18:12:31

YOLOv13 AP高达54.8?实测验证官方数据真实性

YOLOv13 AP高达54.8&#xff1f;实测验证官方数据真实性 近年来&#xff0c;YOLO系列目标检测模型持续迭代&#xff0c;从v1到v8再到后续版本&#xff0c;每一次更新都引发业界广泛关注。近期&#xff0c;Ultralytics团队发布了号称“下一代实时检测器”的YOLOv13&#xff0c;…

作者头像 李华
网站建设 2026/5/28 10:28:37

YOLOv10摄像头实时检测,Python脚本一键运行

YOLOv10摄像头实时检测&#xff0c;Python脚本一键运行 随着目标检测技术的不断演进&#xff0c;YOLOv10 以其端到端无NMS设计和极致推理效率成为边缘计算与实时视觉应用的新标杆。相比前代版本&#xff0c;YOLOv10 不仅在精度上保持领先&#xff0c;在延迟和部署复杂度方面实…

作者头像 李华