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博客