C语言读取 ini 配置文件,修改/添加键值对

C语言读取 ini 配置文件,修改/添加键值对

C语言读取 ini 配置文件,对section中的键值对进行修改/添加,如果section不存在,则在末尾将新的section/key/value 添加进去。

一、了解什么是INI文件?

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

二、INI文件的格式

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

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

/*test.ini*/
[city]
beijing =  hello-beijing
shanghai = hello-shanghai#information
[study]
highschool = huafuyi
university = guofangkeda[xinming]
name = lilei

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

  • 读取key对应的value值


/** 功能:     读取key对应的value值* 入口参数: filename*                要读取的文件路径*            title*                配置文件中一组数据的标识*            key*                这组数据中要读出的值的标识* 返回值:   找到需要查的值则返回正确结果 0*            否则返回-1*/
int GetIniKeyString(char* filename, char* title, char* key, char* buf)
{FILE* fp;int  flag = 0;char sTitle[64], * wTmp;char sLine[1024];// 节section字符串sprintf(sTitle, "[%s]", title);if (NULL == (fp = fopen(filename, "r"))) {printf("open %s failed.\n", filename);perror("fopen failed.\n");return -1;}// 读取ini中的每一行while (NULL != fgets(sLine, 1024, fp)) {// 处理ini文件中的注释行if (0 == strncmp("//", sLine, 2)) continue;if (('#' == sLine[0]) || ';' == 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++;}// 获取key对应的valuestrcpy(buf, wTmp + 1);return 0;}}else {if (0 == strncmp(sTitle, sLine, strlen(sTitle))) { // 长度依文件读取的为准  // 不存在键值对的情况下,标记flagflag = 1; // 找到标题位置  }}}fclose(fp);return -1;
}
  • 修改/添加key-value键值对


/*OK--查找section中是否存在key,存在则将key对应的值修改为val,不存在则将key对应的val添加在section后面。*/
int PutIniKeyString2(char* filename, char* title, char* key, char* val)
{FILE* fpr, * fpw;int  flag = 0;int rtn = 0;char sLine[1024], sTitle[32], * wTmp;sprintf(sTitle, "[%s]", title);if (NULL == (fpr = fopen(filename, "r"))){printf("读取原文件失败.\n");return -1;// 读取原文件 }// 临时文件名sprintf(sLine, "%s.tmp", filename);if (NULL == (fpw = fopen(sLine, "w"))){printf("写入失败.\n");return -1;// 写入临时文件    }while (NULL != fgets(sLine, 1024, fpr)){if (2 != flag){ // 如果找到要修改的那一行,则不会执行内部的操作  wTmp = strchr(sLine, '=');if ((1 == flag)){// 找到对应的keyif ((NULL != wTmp) && (0 == strncmp(key, sLine, strlen(key)))){ // 长度依文件读取的为准 flag = 2;// 更改值,方便写入文件  sprintf(wTmp + 1, " %s\n", val);}else{if ((sLine[0] == '\n')){/* 没有找到对应的key,则在section末尾添加新的key/value *///fseek(fpw, 0, SEEK_END);-((long)strlen(sLine))fseek(fpw, 0, SEEK_CUR);fprintf(fpw, "%s = %s\n", key, val);flag = 0;}}}else{// 找到section的位置if (0 == strncmp(sTitle, sLine, strlen(sTitle))){ // 长度依文件读取的为准flag = 1; // 找到标题位置  }}}fputs(sLine, fpw); // 写入临时文件 }if (-1 == flag){   /* 没有找到对应的section,则在文件末尾添加新的section/key/value */fseek(fpw, 0, SEEK_END);fprintf(fpw, "%s\n", sTitle);fprintf(fpw, "%s = %s\n\n", key, val);}fclose(fpr);fclose(fpw);sprintf(sLine, "%s.tmp", filename);rtn = rename(sLine, filename);// 将临时文件更新到原文件  if (rtn != 0){if (errno == EEXIST){// 如果目标文件已经存在,需要先删除,再重命名if (remove(filename) == 0){if (rename(sLine, filename) == 0){return 0;}else{return -1;}}}}return rtn;
}
  • 测试程序

头文件 ini.h

#pragma once#include <stdio.h>
#include <stdlib.h>
#include <string.h>constexpr auto BUF_SIZE = 256;int GetIniKeyString(char* filename, char* title, char* key, char* buf);int PutIniKeyString2(char* filename, char* title, char* key, char* val);

主函数 main.c

#include "ini.h"int main(int argc, char const* argv[])
{int ret;char buff[100];//readSpeed();//readExcel();int xishu_gain = 2 << 25;//滤波器系数放大倍数.*******************OK**************************char filename[] = "./test.ini";char title[] = "city";char key[] = "beijing";ret = GetIniKeyString(filename, title, key, buff);//读取ini文件key对应的vlaueprintf("ret:%d,%s\n", ret, buff);char filename[] = "./test.ini";//char title2[] = "study";//char key2[] = "highschool";//ret = GetIniKeyString(filename, title2, key2, buff);//读取ini文件key对应的vlaue//printf("ret:%d,%s\n", ret, buff);char title3[] = "xinming";char key3[] = "name2";char value3[] = "xiao-hua";ret = PutIniKeyString2(filename, title3, key3, value3);//修改ini文件key对应的vlaueprintf("put ret:%d,%s\n", ret, value3);//ret = GetIniKeyString(filename, title3, key3, buff);//printf("ret:%d,%s\n", ret, buff);//****************OK*****************************return 0;
}

测试结果ini文件:

/*test.ini*/
[city]
beijing =  hello-beijing
shanghai = hello-shanghai
wuhan = hello-wuhan
wuhan1 = hello-wu-han
wuhan2 = hello-wuhan#information
[study]
highschool = huafuyi
university = guofangkeda
xiaoxue = huafucunxiao
xiaoxue1 = huafu-cunxiao1[xinming]
name = lilei
name1 = xiao-ming1
name2 = xiao-hua
/*test.ini*/
[city]
beijing =  hello-beijing
shanghai = hello-shanghai
wuhan = hello-wuhan
wuhan1 = hello-wu-han
wuhan2 = hello-wuhan#information
[study]
highschool = huafuyi
university = guofangkeda
xiaoxue = huafucunxiao
xiaoxue1 = huafu-cunxiao1[xinming]
name = lilei
name1 = xiao-ming1
name2 = xiao-hua[tizhi]
weight = 80kg
weight1 = 80kg

  • 打开或创建名为"config.ini"的文件

{FILE* file = fopen("config.ini", "w");//打开或创建名为"config.ini"的文件if (file == NULL){printf("无法创建文件\n");return -1;}// 写入配置项到文件fprintf(file, "[Section]\n");fprintf(file, "key=value\n");fprintf(file, "\n[Another Section]\n");fprintf(file, "another_key=another_value\n");fclose(file); // 关闭文件
}

参考:

1、C语言读取写入 ini 配置文件_c读取ini配置文件-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/696777.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【大数据】Flink 之部署篇

Flink 之部署篇 1.概述和参考架构2.可重复的资源清理3.部署模式3.1 Application 模式3.2 Per-Job 模式&#xff08;已废弃&#xff09;3.3 Session 模式 Flink 是一个多用途框架&#xff0c;支持多种不同的混合部署方案。下面&#xff0c;我们将简要介绍 Flink 集群的构建模块、…

【html学习笔记】3.表单元素

1.文本框 1.1 语法 <input type "text">表示文本框。且只能写一行 1.2 属性 使用属性size 设置文本框大小 <input type"text" size"10">2. 使用属性value 来设置文本框的默认文字 <input type"text" size"…

Vue状态管理库-Pinia

一、Pinia是什么&#xff1f; Pinia 是 Vue 的专属状态管理库&#xff0c;它允许支持跨组件或页面共享状态&#xff0c;即共享数据&#xff0c;他的初始设计目的是设计一个支持组合式API的 Vue 状态管理库&#xff08;因为vue3一个很大的改变就是组合式API&#xff09;,当然这…

PFA三角烧瓶实验室PFA锥形瓶本底纯净耐腐蚀性强

PFA三角烧瓶外观呈平底圆锥状&#xff0c;下阔上狭&#xff0c;有一圆柱形颈部&#xff0c;上方有一较颈部阔的开口&#xff0c;可用塞子封闭。PFA三角烧瓶也称PFA锥形瓶&#xff0c;PFA反应瓶&#xff0c;PFA三角烧瓶、PFA依氏烧瓶、PFA锥形烧瓶&#xff0c;PFA鄂伦麦尔瓶等。…

普中51单片机学习(串口通信)

串口通信 原理 计算机通信是将计算机技术和通信技术的相结合&#xff0c;完成计算机与外部设备或计算机与计算机之间的信息交换 。可以分为两大类&#xff1a;并行通信与串行通信。并行通信通常是将数据字节的各位用多条数据线同时进行传送 。控制简单、传输速度快&#xff1…

【Python】Python实现串口通信(Python+Stm32)

&#x1f389;欢迎来到Python专栏~Python实现串口通信 ☆* o(≧▽≦)o *☆嗨~我是小夏与酒&#x1f379; ✨博客主页&#xff1a;小夏与酒的博客 &#x1f388;该系列文章专栏&#xff1a;Python学习专栏 文章作者技术和水平有限&#xff0c;如果文中出现错误&#xff0c;希望…

springboot208基于springboot物流管理系统

基于spring boot物流管理系统设计与实现 摘 要 社会发展日新月异&#xff0c;用计算机应用实现数据管理功能已经算是很完善的了&#xff0c;但是随着移动互联网的到来&#xff0c;处理信息不再受制于地理位置的限制&#xff0c;处理信息及时高效&#xff0c;备受人们的喜爱。…

maven工程打包引入本地jar包

1、通过maven生成本地区仓库包 mvn install:install-file --settings D:\lkx\download\apache-maven-3.6.3\conf\settings.xml -Dfileaspose-cad-21.8.jar -DartifactIdaspose-cad -DgroupIdsystem.core -Dversion21.8 -Dpackagingjar -DgeneratePomtrue # --settings&#xf…

进程线程间的通信:2024/2/22

作业1&#xff1a;代码实现线程互斥机制 代码&#xff1a; #include <myhead.h>//临界资源 int num10;//创建一个互斥锁 pthread_mutex_t mutex;//任务一 void *task1(void *arg) {//获取锁资源pthread_mutex_lock(&mutex);num123;sleep(3);printf("task1:num…

PacketSender-用于发送/接收 TCP、UDP、SSL、HTTP 的网络实用程序

PacketSender-用于发送/接收 TCP、UDP、SSL、HTTP 的网络实用程序 PacketSender是一款开源的用于发送/接收 TCP、UDP、SSL、HTTP 的网络实用程序&#xff0c;作者为dannagle。 其官网地址为&#xff1a;https://packetsender.com/&#xff0c;Github源代码地址&#xff1a;htt…

SQL Server —— While语句循环

一&#xff1a;简介 while 循环是有条件的循环控制语句。满足条件后&#xff0c;再执行循环体中的SQL语句。 while: break, 如果有多条语句可以在while后面添加begin-end。关于while的语法 while(条件) -- begin -- 语句1 -- 语句2 -- break 根据情况是否添加break -- end 二…

leetcode日记(32)字符串相乘

做了很久很久……真的太繁琐了&#xff01;&#xff01; class Solution { public:string multiply(string num1, string num2) {string s;string str;if (num1 "0" || num2 "0") return "0";for(int inum2.size()-1;i>0;i--){int c2num2[…

Qt:tabWidget控件

一、tabWidget用来做什么 tabWidget控件用来进行不同控件页面的跳转&#xff0c; 二、控件的一些函数功能 添加一个页面&#xff0c;返回index int addTab(QWidget *widget, const QString &); int addTab(QWidget *widget, const QIcon& icon, const QString &…

pytest教程-11-初识fixture

领取资料&#xff0c;咨询答疑&#xff0c;请➕wei: June__Go 上一小节我们学习了使用allure生成html测试报告的方法&#xff0c;本小节我们讲解一下pytest fixture测试夹具的使用方法。 前言 在做自动化的过程中&#xff0c;编写用例时候需要用到用例的前置和用例的后置&a…

2024年了,抖店还能做吗?适合新手吗?

我是电商珠珠 现在已经24年了&#xff0c;抖店也已经发展了四年了。其中有很多在门外观望的人&#xff0c;还在犹豫不决。认为抖店发展到今天&#xff0c;所有的红利早已在20年的时候就消失殆尽了&#xff0c;特别是没有经验的如果入驻了&#xff0c;既不能享受平台红利&#…

后端程序员入门react笔记(四)-综合运用,写一个小demo

样式模块化 有时候我们会遇到这样的问题&#xff0c;有两个css对一个class声明了样式&#xff0c;这样的话后引入的css会覆盖前面的css样式&#xff0c;导致样式冲突&#xff0c;那么我们怎么解决这种问题呢&#xff0c;我们可以使用样式的模块化&#xff0c;我们起名一个inde…

OpenHarmony驱动框架HDF中设备管理服务构建过程详解

前言 如下图&#xff0c;开源鸿蒙系统驱动框架HDF在内核中的实现&#xff0c;可以分为向用户层提供设备服务的管理模块&#xff08;Manager&#xff09;&#xff0c;和实际管理硬件的Host模块。 Manager分为DeviceManageService和 DeviceServiceManage&#xff0c;前者负责提供…

1.WEB渗透测试-前置基础知识-ip地址

ip地址&#xff1a; ip地址指的是互联网协议地址&#xff0c;是IP协议提供的一种统一的地址格式&#xff0c;以每一台联网的主机都有一个对应的ip地址&#xff0c;ip地址也可以理解为分配给用户上网使用的网际协议的设备的数字标签。通俗的来说就是你打电话时候的每个人都有自己…

在Mac上搭建MongoDB环境

最近工作中需要装MongoDB环境&#xff0c;搭建过程中遇到了一些问题&#xff0c;在这里记录一下安装MongoDB环境的方法以及问题的解决方法。有两种安装MongoDB的方法&#xff1a;brew安装和手动安装。 目录 使用Homebrew安装MongoDB 手动安装MongoDB&#xff08;不使用Homebr…

vue--两种定时任务cron表达式组件比较选择

背景&#xff1a; 使用vue页面中cron表达式的组件&#xff0c;实现定时任务参数配置。 方案1 vue-cron 安装插件 npm install vue-cron --save 全局引入&#xff0c;修改main.js import Vue from vue import VueCron from vue-cron Vue.use(VueCron);页面配置 html<el-…