CFG、INI配置文件读写C程序
- 格式:docx
- 大小:33.44 KB
- 文档页数:22
C语⾔读取配置⽂件⾃从⼤学学完C之后,就再也没⽤过它了,在⽹上找代码,七拼⼋凑之后,终于成形~~勉强能⽤,不喜勿喷,^_^!int GetValue(const wchar_t *key, wchar_t *value){FILE* fpcfg = NULL;wchar_t var[256], val[256];//key,valuewchar_t linebuf[1024];wchar_t* ptr1 = NULL;wchar_t* ptr2 = NULL;wchar_t* delimiter = NULL;int k = 0;assert(key != NULL && value != NULL);//testConfig.ini中的内容为://key1 = value1//key2 = value2fpcfg = fopen("testConfig.ini", "rt");if(fpcfg == NULL){return -1;}while(fgetws(linebuf, sizeof(linebuf), fpcfg) != NULL){//ignore annotation lineif(linebuf[0]=='#' || linebuf[0]==';'){continue;}//ignore empty lineptr1 = linebuf;while(*ptr1==0x20 || *ptr1=='\t')ptr1++;if(!*ptr1 || *ptr1=='\n'){continue;}//search "="ptr2 = ptr1;while(*ptr2 && *ptr2!='='){ptr2++;}delimiter = *ptr2?ptr2:NULL;//if current line start with "=", continue next lineif(!delimiter || delimiter==ptr1){continue;}//*delimiter = '\0';ptr2 = delimiter-1;//ignore blank before "="while(*ptr2==0x20 || *ptr2=='\t'){ ptr2--;}//check key lengthk = ptr2-ptr1+1;if(k>(int)sizeof(var)-1){//The key name is out of length."continue;}//save key nameptr2 = var;while(k--){*ptr2++ = *ptr1++;}*ptr2 = '\0';//locate value's start point(may be '\0')ptr1 = delimiter+1;//ignore blank after "="while(*ptr1==0x20 || *ptr1=='\t'){ptr1++;}//set ptr2 point to line endptr2 = linebuf;while(*ptr2){ptr2++;}ptr2--;if(*ptr2=='\n'){*ptr2-- = '\0';}//ignore blank line end//if value is empty,ptr2 --> = , ptr1>ptr2while(*ptr2==0x20 || *ptr2=='\t' ){ptr2--;}//check value lengthk = ptr2-ptr1+1;if(k>(int)sizeof(val)-1){//The value is out of length"continue;}//save valueptr2 = val;while(k-->0){*ptr2++ = *ptr1++;}*ptr2 = '\0';if(wcsncmp(var,key, wcslen(var) > wcslen(key) ? wcslen(var) : wcslen(key))==0){ wcsncpy(value,val, wcslen(val));return0;}}fclose(fpcfg);fpcfg = NULL;return -1;}恩,再来个main⽅法测试下:int _tmain(int argc, wchar_t* argv[]){wchar_t value[256] = {0};wchar_t keyParam[256] = L"ip";wchar_t *temp = (wchar_t *)malloc(sizeof(wchar_t) * 256);if(temp != NULL){memset(temp, 0x00, sizeof(wchar_t) * 256);}else{return -1;}if(0 == GetValue(keyParam, temp)){wcsncpy(value, temp, wcslen(temp));wprintf(L"Found: %s\n", value);}else{wprintf(L"Not Found!!\n");}if(temp != NULL){free(temp);temp = NULL;}return0;}View Code好吧,这确实是个很丑陋的版本,仅供⾃⼰留着备⽤。
C语⾔读取写⼊ini配置⽂件的⽅法实现⽬录⼀、了解什么是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 <stdio.h>#include <string.h>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 <stdio.h>#include <string.h>/** 函数名: 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-beijingshanghai = hello-shanghai#information[study]highschool = xxxxuniversity = yyyytest.c程序/*test.c*/#include "ini.h"#include <stdio.h>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-beijingret:0,xxxxput ret:0ret:0,zzzz相应的test.ini的study段highschool项变成了zzzz.这⾥还要注意,section使⽤中⽂字符可能会⽆法识别!到此这篇关于C语⾔读取写⼊ini配置⽂件的⽅法实现的⽂章就介绍到这了,更多相关C语⾔读取写⼊ini 内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。
c语⾔读写配置⽂件配置⽂件的格式如下:key1 = value1key2 = value2中间及前后可以有多个空格思路分析: 读写配置⽂件可以分成底层API接⼝和调⽤API的界⾯⼆个模块,⼆个模块间耦合度要尽量低,底层封装的API要尽量好⽤。
不要让⼈家写⽂件的时候还需要⾃⼰去判断配置项是否已经存在,这些功能底层API要做完善。
⼀接⼝设计 既然是读写,提供给外部⼀个读取的接⼝和⼀个写⼊的接⼝就可以了。
要让⼆个接⼝⽅便好⽤int writeCFG(const char *filename/*in*/, const char *key/*in*/, const char *value/*in*/);//写⼊配置⽂件void readCFG(const char *filename/*in*/, const char *key/*in*/, const char **value/*out*/);//读取配置⽂件⼆框架搭建 ReadAndWrite.h 函数原型 void trim(char *strIn, char *strOut);//去除字符串前⾯和后⾯的空格void getValue(char * keyAndValue, char * key, char * value);//根据key得到valueint writeCFG(const char *filename/*in*/, const char *key/*in*/, const char *value/*in*/);//写⼊配置⽂件void readCFG(const char *filename/*in*/, const char *key/*in*/, const char **value/*out*/);//读取配置⽂件三代码实现 ReadAndWrite.c 函数实现void trim(char *strIn, char *strOut){char *start, *end, *temp;//定义去除空格后字符串的头尾指针和遍历指针temp = strIn;while (*temp == ''){++temp;}start = temp; //求得头指针temp = strIn + strlen(strIn) - 1; //得到原字符串最后⼀个字符的指针(不是'\0')while (*temp == ''){--temp;}end = temp; //求得尾指针for(strIn = start; strIn <= end; ){*strOut++ = *strIn++;}*strOut = '\0';}void getValue(char * keyAndValue, char * key, char * value){char *p = keyAndValue;p = strstr(keyAndValue, key);//找到key的位置,指针if(p == NULL){printf("没有key %s\n", key);return ;}p += strlen(key);//指针后移到key后⾯trim(p, value);p = strstr(value, "=");//找等号的位置if(p == NULL){printf("没有找到=\n");return;}p+= strlen("=");//指针后移到等号后⾯trim(p, value);//删除字符串前后的空格}int writeCFG(const char *filename/*in*/, const char *key/*in*/, const char *value/*in*/){ FILE *pf = NULL;char ftemp[flen] = {0}, fline[1024] = {0}, *fp; //⽂件缓存数组long fsize = 0;int reg = 0;int exit = 0;int i = 0; int flen = 8*1024;pf = fopen(filename, "r+");if(pf == NULL){pf = fopen(filename, "w+");}//获得⽂件⼤⼩fseek(pf, 0, SEEK_END); // 将⽂件指针pf指向末尾fsize = ftell(pf);//获取⽂件开头到pf的长度if(fsize > flen){printf("⽂件不能超过8k\n");reg = -1;goto end;}fseek(pf, 0, SEEK_SET); //将⽂件指针指向开头//⼀⾏⼀⾏的读,如果存在key则修改value存到缓存数组中while(!feof(pf)){//未到⽂件结尾fgets(fline, 1024, pf);if(strstr(fline, key) != NULL && exit == 1)strcpy(fline, "");if(strstr(fline, key) != NULL && exit == 0){ //判断key是否存在exit = 1;sprintf(fline,"%s = %s\n", key, value);}printf("fline = %s\n", fline);strcat(ftemp, fline);}if(exit != 1){//如果不存在则把key value写⼊到最后⼀⾏sprintf(fline,"%s = %s\n", key, value);strcat(ftemp, fline);}if(pf != NULL){fclose(pf);pf = fopen(filename, "w+");fp = (char *)malloc(sizeof(char) * strlen(ftemp) + 1);strcpy(fp, ftemp);fp[strlen(fp) - 1] = EOF;fputs(fp, pf);if(fp != NULL){free(fp);fp = NULL;}fclose(pf);}end :if(pf != NULL)fclose(pf);//重新创建⼀个以filename命名的⽂件return reg;}void readCFG(const char *filename/*in*/, const char *key/*in*/, const char **value/*out*/){ FILE *pf = NULL;char line[1024] = {0}, vtemp[1024] = {0};pf = fopen(filename, "r"); //以只读⽅式打开while(!feof(pf)){fgets(line, 1024, pf);getValue(line, key, vtemp);if(strlen(vtemp) != 0)break;}if(strlen(vtemp) != 0){*value = (char *)malloc(sizeof(char) * strlen(vtemp) + 1);strcpy(*value, vtemp);}else*value = NULL;if(pf != NULL)fclose(pf);}测试界⾯代码:#define filename "c:/cfg.ini"void menu(){printf("===========================\n");printf("1 写⼊配置⽂件\n");printf("2 读取配置⽂件\n");printf("0 退出程序");printf("===========================\n");}int tWrite(){char key[1024] = {0}, value[1024] = {0};printf("请输⼊key:");scanf("%s", key);printf("请输⼊value:");scanf("%s", value);printf("\n您输⼊的是:%s = %s\n", key, value);return writeCFG(filename/*in*/,key/*in*/,value/*in*/);}void tRead(){char key[1024] = {0}, *value;printf("请输⼊key:");scanf("%s", key);readCFG(filename/*in*/,key/*in*/, &value/*out*/);if(value == NULL){printf("没有key\n");return ;}printf("\nvalue = %s\n", value);if(value != NULL){free(value);value = NULL;}}int main(){int choose;while(1){choose = 0;menu();printf("请输⼊选择:");scanf("%d", &choose);switch(choose){case1:if(tWrite() == -1)return -1;break;case2:tRead();break;case0:return0;default:return0;}}system("pause"); return0;}。
ini配置⽂件读写-⽰例类:1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.Threading.Tasks;6using IniTool;7using System.Drawing;8using Utils;9using System.Collections;1011namespace AppConfig12 {13public class Config14 {15private static string file = Environment.CurrentDirectory + @"\config.ini";16private static Config _Config = new Config();17private bool _isInit = false;1819private enum Control20 {21 ADD,22 READ,23 WRITE,24 }2526public enum Sections27 {28 SerialConfig,29 ActionConfig,30 ColorConfig,31 DrawConfig32 }3334public enum Idents35 {36 Baud,37 DataBits,38 Parity,39 StopBits,40 CloseAction,41 CanvasColor,42 GridColor,43 PointColor,44 LocateColor,45 DrawRows,46 DrawCols47 }4849public bool IsInit50 {51get{ return _isInit; }52private set { _isInit = value; }53 }5455public class Data56 {57private Sections _section;58private Idents _ident;59private string _val;6061public Sections section { get { return _section; } set { _section = value; } }62public Idents ident { get { return _ident; } set { _ident = value; } }63public string val { get { return _val; } set { _val = value; } }6465public Data(Sections section, Idents ident, string val)66 {67this.section = section;68this.ident = ident;69this.val = val;70 }71 }7273private List<Data> ConfigList = new List<Data>();74private List<string> DataSections = new List<string>();75private List<string> DataIdents = new List<string>();7677public Config()78 {7980 }8182public static Config Cfg83 {84get { return _Config; }85 }8687public void InitConfig()88 {89 Console.WriteLine("配置初始化");9091//检测配置⽂件是否存在并加载92bool result = ini_RW.CheckIniFile(file);93//初始化数据94 InitData();9596if (result)97 {98this.IsInit = true;99//增加100 AddConfig();101//删除失效配置102 UpdateConfig();103//读取104 ReadConfig();105 }106 }107108private void InitData()109 {110//初始化串⼝参数111 ConfigList.Add(new Data(Sections.SerialConfig, Idents.Baud, "9600"));112 ConfigList.Add(new Data(Sections.SerialConfig, Idents.DataBits, "8"));113 ConfigList.Add(new Data(Sections.SerialConfig, Idents.Parity, "None"));114 ConfigList.Add(new Data(Sections.SerialConfig, Idents.StopBits, "One"));115116//初始化关闭按钮功能117 ConfigList.Add(new Data(Sections.ActionConfig, Idents.CloseAction, "True")); 118119//初始化颜⾊数据120 ConfigList.Add(new Data(Sections.ColorConfig, Idents.CanvasColor, "White")); 121 ConfigList.Add(new Data(Sections.ColorConfig, Idents.GridColor, "Gray"));122 ConfigList.Add(new Data(Sections.ColorConfig, Idents.PointColor, "DarkOrange")); 123 ConfigList.Add(new Data(Sections.ColorConfig, Idents.LocateColor, "Blue"));124125//初始化绘制参数126 ConfigList.Add(new Data(Sections.DrawConfig, Idents.DrawRows, "128"));127 ConfigList.Add(new Data(Sections.DrawConfig, Idents.DrawCols, "128"));128129 }130131private void AddConfig()132 {133//DataSections.Clear();134//DataIdents.Clear();135 Manage(Control.ADD);136 }137138private void UpdateConfig()139 {140//检测是否有更改141var Sections = ini_RW.ReadSections();142foreach (var section in Sections)143 {144//检测节点是否存在145if (!DataSections.Exists(x => x == section))146 {147//不存在删除148 ini_RW.DeleteSection(section);149 }150else151 {152//检测数据是否存在153var idents = ini_RW.ReadIdents(section);154foreach (var ident in idents)155 {156if (!DataIdents.Exists(y => y == ident))157 {158//不存在删除159 ini_RW.DeleteIdent(section, ident);160 }161 }162 }163 }164 }165166private void ReadConfig()167 {168 Manage(Control.READ);169 }170171public void WriteConfig()172 {173 Manage(Control.WRITE);174 }175176private void Manage(Control type)177 {178 (from item in ConfigList179select item).180 ToList().181 ForEach(x => {182183switch (type)184 {185case Control.ADD:186 {187 ini_RW.AddConfigInfo(x.section.ToString(), x.ident.ToString(), x.val); 188189 DataSections.Add(x.section.ToString());190 DataIdents.Add(x.ident.ToString());191 }192break;193case Control.READ:194 {195 x.val = ini_RW.ReadIni(x.section.ToString(), x.ident.ToString()); 196 }197break;198case Control.WRITE:199 {200 ini_RW.WriteIni(x.section.ToString(), x.ident.ToString(), x.val);201 }202break;203 }204 });205 }206207public Data GetConfig(Sections section, Idents ident)208 {209return (from item in ConfigList210where (item.section == section && item.ident == ident)211select item).FirstOrDefault();212 }213214215//############################################################### 216//private static Config _Config = null;217//private static object Config_Lock = new object();218219//public static Config Init()220//{221// if (_Config == null)222// {223// lock (Config_Lock)224// {225// if (_Config == null)226// {227// _Config = new Config();228// }229// }230// }231// return _Config;232//}233//################################################################ 234235 }236 }调⽤:1//程序打开时初始化2 Config.Cfg.InitConfig();3if (!Config.Cfg.IsInit)4 {5 MessageBox.Show("配置⽂件不存在", "提⽰", MessageBoxButtons.OK, MessageBoxIcon.Warning);6 }78//程序退出时保存9if (Config.Cfg.IsInit)10 {11 Config.Cfg.WriteConfig();12 }。
C语言读取INI配置文件Ini.h#pragma once#include"afxTempl.h"class DLLPORT CIni{private:CString m_strFileName;public:CIni(CString strFileName) :m_strFileName(strFileName){}public://一般性操作:BOOL SetFileName(LPCTSTR lpFileName); //设置文件名CString GetFileName(void); //获得文件名BOOL SetValue(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpValue, bool bCreate = true); //设置键值,bCreate是指段名及键名未存在时,是否创建。
CString GetValue(LPCTSTR lpSection, LPCTSTR lpKey); //得到键值.BOOL DelSection(LPCTSTR strSection); //删除段名BOOL DelKey(LPCTSTR lpSection, LPCTSTR lpKey); //删除键名public://高级操作:int GetSections(CStringArray& arrSection); //枚举出全部的段名int GetKeyValues(CStringArray& arrKey, CStringArray& arrValue, LPCTSTR lpSection); //枚举出一段内的全部键名及值BOOL DelAllSections();};/*使用方法:CIni ini("c:\\a.ini");int n;/*获得值TRACE("%s",ini.GetValue("段1","键1"));*//*添加值ini.SetValue("自定义段","键1","值");ini.SetValue("自定义段2","键1","值",false);*//*枚举全部段名CStringArray arrSection;n=ini.GetSections(arrSection);for(int i=0;i<n;i++)TRACE("%s\n",arrSection[i]);*//*枚举全部键名及值CStringArray arrKey,arrValue;n=ini.GetKeyValues(arrKey,arrValue,"段1");for(int i=0;i<n;i++)TRACE("键:%s\n值:%s\n",arrKey[i],arrValue[i]); *//*删除键值ini.DelKey("段1","键1");*//*删除段ini.DelSection("段1");*//*删除全部ini.DelAllSections();*/Ini.cpp#include"StdAfx.h"#include"Ini.h"#define MAX_ALLSECTIONS 2048 //全部的段名#define MAX_SECTION 260 //一个段名长度#define MAX_ALLKEYS 6000 //全部的键名#define MAX_KEY 260 //一个键名长度BOOL CIni::SetFileName(LPCTSTR lpFileName){CFile file;CFileStatus status;if (!file.GetStatus(lpFileName, status))return TRUE;m_strFileName = lpFileName;return FALSE;}CString CIni::GetFileName(void){return m_strFileName;}BOOL CIni::SetValue(LPCTSTR lpSection, LPCTSTR lpKey, LPCTSTR lpValue, bool bCreate) {TCHAR lpTemp[MAX_PATH] = { 0 };//以下if语句表示如果设置bCreate为false时,当没有这个键名时则返回TRUE(表示出错)//!*&*none-value*&!* 这是个垃圾字符没有特别意义,这样乱写是防止凑巧相同。
c#winform程序读写ini配置⽂件背景:本来准备使⽤settings.settings来保存数据库配置等信息的。
但是设置为“应⽤程序”级别,就没法⽅便的⽤Properties.Settings.Default.Save() 更改保存。
且没法在程序不重启的情况下应⽤修改后的配置。
如果设置为“⽤户”级别,就存在配置信息保存到appData⽂件夹下被清空缓存失效的风险。
因此回过头来选择ini来保存这些配置信息⽹上找了个ini读写操作类,直接copy拿来⽤,测试可⽤,代码如下:using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.IO;using System.Runtime.InteropServices;namespace data_migration_desk.utils{// INI⽂件操作类class IniFileHelper{string strIniFilePath; // ini配置⽂件路径// 返回0表⽰失败,⾮0为成功[DllImport("kernel32", CharSet = CharSet.Auto)]private static extern long WritePrivateProfileString(string section, string key, string val, string filePath);// 返回取得字符串缓冲区的长度[DllImport("kernel32", CharSet = CharSet.Auto)]private static extern long GetPrivateProfileString(string section, string key, string strDefault, StringBuilder retVal, int size, string filePath);[DllImport("Kernel32.dll", CharSet = CharSet.Auto)]public static extern int GetPrivateProfileInt(string section, string key, int nDefault, string filePath);///<summary>///⽆参构造函数///</summary>///<returns></returns>public IniFileHelper(){this.strIniFilePath = Directory.GetCurrentDirectory() + "\\Properties\\sysconfig.ini";}///<summary>///有参构造函数///</summary>///<param name="strIniFilePath">ini配置⽂件路径</param>///<returns></returns>public IniFileHelper(string strIniFilePath){if (strIniFilePath != null){this.strIniFilePath = strIniFilePath;}}///<summary>///获取ini配置⽂件中的字符串///</summary>///<param name="section">节名</param>///<param name="key">键名</param>///<param name="strDefault">默认值</param>///<param name="retVal">结果缓冲区</param>///<param name="size">结果缓冲区⼤⼩</param>///<returns>成功true,失败false</returns>public bool GetIniString(string section, string key, string strDefault, StringBuilder retVal, int size){long liRet = GetPrivateProfileString(section, key, strDefault, retVal, size, strIniFilePath);return (liRet >= 1);}///<summary>///获取ini配置⽂件中的整型值///</summary>///<param name="section">节名</param>///<param name="key">键名</param>///<param name="nDefault">默认值</param>///<returns></returns>public int GetIniInt(string section, string key, int nDefault){return GetPrivateProfileInt(section, key, nDefault, strIniFilePath);}///<summary>///往ini配置⽂件写⼊字符串///</summary>///<param name="section">节名</param>///<param name="key">键名</param>///<param name="val">要写⼊的字符串</param>///<returns>成功true,失败false</returns>public bool WriteIniString(string section, string key, string val){long liRet = WritePrivateProfileString(section, key, val, strIniFilePath);return (liRet != 0);}///<summary>///往ini配置⽂件写⼊整型数据///</summary>///<param name="section">节名</param>///<param name="key">键名</param>///<param name="val">要写⼊的数据</param>///<returns>成功true,失败false</returns>public bool WriteIniInt(string section, string key, int val){return WriteIniString(section, key, val.ToString());}}}使⽤⽅法:读取:IniFileHelper iniFileHelper = new IniFileHelper();StringBuilder sb = new StringBuilder(60);iniFileHelper.GetIniString("tokeninfo", "apiUrl", "", sb, sb.Capacity);string aaa = sb.ToString();写⼊:IniFileHelper iniFileHelper = new IniFileHelper();iniFileHelper.WriteIniString("tokeninfo", "apiUrl", "newString");其中,ini配置⽂件有⼀些需要讲究的地⽅,不然,就会出现读取不到值的情况。
c使用inifile案例IniFile是一个用于处理INI文件的C库,它提供了一些函数来读取、写入和修改INI文件中的配置项。
INI文件是一种常见的配置文件格式,通常用于保存程序的配置信息。
以下是使用IniFile库进行INI 文件操作的一些示例:1. 创建INI文件并写入配置项```#include <stdio.h>#include <inifile.h>int main() {IniFile* ini = inifile_create("config.ini");inifile_set_string(ini, "Section1", "Key1", "Value1");inifile_set_int(ini, "Section1", "Key2", 123);inifile_set_double(ini, "Section2", "Key3", 3.14);inifile_save(ini);inifile_destroy(ini);return 0;}```2. 读取INI文件中的配置项```#include <stdio.h>#include <inifile.h>int main() {IniFile* ini = inifile_load("config.ini");char* value1 = inifile_get_string(ini, "Section1", "Key1", NULL); int value2 = inifile_get_int(ini, "Section1", "Key2", 0);double value3 = inifile_get_double(ini, "Section2", "Key3", 0.0); printf("Value1: %s\n", value1);printf("Value2: %d\n", value2);printf("Value3: %f\n", value3);inifile_destroy(ini);return 0;}```3. 修改INI文件中的配置项```#include <stdio.h>#include <inifile.h>int main() {IniFile* ini = inifile_load("config.ini");inifile_set_string(ini, "Section1", "Key1", "NewValue1");inifile_set_int(ini, "Section1", "Key2", 456);inifile_set_double(ini, "Section2", "Key3", 2.718); inifile_save(ini);inifile_destroy(ini);return 0;}```4. 删除INI文件中的配置项```#include <stdio.h>#include <inifile.h>int main() {IniFile* ini = inifile_load("config.ini");inifile_remove_key(ini, "Section1", "Key1");inifile_remove_key(ini, "Section1", "Key2");inifile_remove_key(ini, "Section2", "Key3");inifile_save(ini);inifile_destroy(ini);return 0;}```5. 遍历INI文件中的所有配置项```#include <stdio.h>#include <inifile.h>int main() {IniFile* ini = inifile_load("config.ini");IniSection* section = ini->sections;while (section != NULL) {printf("[%s]\n", section->name);IniItem* item = section->items;while (item != NULL) {printf("%s=%s\n", item->key, item->value);item = item->next;}section = section->next;}inifile_destroy(ini);return 0;}```这些示例展示了使用IniFile库进行INI文件操作的基本方法。
C读取配置⽂件#ifndef __CFG_OP_H__#define __CFG_OP_H__#ifdef __cplusplusextern"C" {#endif//获取配置项int GetCfgItem(char *pFileName /*in*/, char *pKey /*in*/, char * pValue/*in out*/, int * pValueLen /*out*/);//写配置项int WriteCfgItem(char *pFileName /*in*/, char *pItemName /*in*/, char *pItemValue/*in*/, int itemValueLen /*in*/); #ifdef __cplusplus}#endif#endif#define _CRT_SECURE_NO_WARNINGS#include <stdlib.h>#include <string.h>#include <stdio.h>#define MaxLine 2048//获取配置项int GetCfgItem(char *pFileName /*in*/, char *pKey /*in*/, char * pValue/*in out*/, int * pValueLen /*out*/){int ret = 0;FILE *fp = NULL;char *pTmp = NULL, *pEnd = NULL, *pBegin = NULL;char lineBuf[MaxLine];fp = fopen(pFileName, "r");//读的⽅式打开⽂件if (fp == NULL){ret = -1;return ret;}while (!feof(fp))//没有到达⽂件末尾{memset(lineBuf, 0, sizeof(lineBuf));//清空内存空间//fgets(_Out_z_cap_(_MaxCount) char * _Buf, _In_ int _MaxCount, _Inout_ FILE * _File);fgets(lineBuf, MaxLine, fp);//从⽂件中⼀⾏⼀⾏的获取数据//printf("lineBuf:%s ",lineBuf );pTmp = strchr(lineBuf, '='); //有没有等号if (pTmp == NULL) //没有=号{continue;}pTmp = strstr(lineBuf, pKey);//所在⾏是不是有keyif (pTmp == NULL) //判断key是不是在{continue;}pTmp = pTmp + strlen(pKey); //mykey1 = myvalude11111111 ==> "= myvalude1111111"pTmp = strchr(pTmp, '=');if (pTmp == NULL) //判断key是不是在 //所在⾏是不是有key{continue;}pTmp = pTmp + 1;////printf("pTmp:%s ", pTmp);//获取value 起点while (1){if (*pTmp == ''){pTmp ++ ;}else{pBegin = pTmp;if (*pBegin == '\n'){//没有配置value//printf("配置项:%s 没有配置value \n", pKey);goto End;}break;}}//获取valude结束点while (1){if ((*pTmp == '' || *pTmp == '\n')){break;}else{pTmp ++;}}pEnd = pTmp;//赋值*pValueLen = pEnd-pBegin;memcpy(pValue, pBegin, pEnd-pBegin);}End:if (fp == NULL){fclose(fp);}return0;}//写配置项//实现流程//循环读每⼀⾏,检查key配置项是否存在若存在修改对应value值//若不存在,在⽂件末尾添加 "key = value"//难点:如何修改⽂件流中的值int WriteCfgItem(char *pFileName /*in*/, char *pKey /*in*/, char * pValue/*in*/, int ValueLen /*in*/){int rv = 0, iTag = 0, length = 0;FILE *fp = NULL;char lineBuf[MaxLine];char *pTmp = NULL, *pBegin = NULL, *pEnd = NULL;char filebuf[1024*8] = {0};if (pFileName==NULL || pKey==NULL || pValue==NULL){rv = -1;printf("SetCfgItem() err. param err \n");goto End;}fp = fopen(pFileName, "r+");if (fp == NULL){rv = -2;printf("fopen() err. \n");//goto End;}if (fp == NULL)//⽂件不存在就去创建⼀个⽂件{fp = fopen(pFileName, "w+t");if (fp == NULL){rv = -3;printf("fopen() err. \n");goto End;}}fseek(fp, 0L, SEEK_END); //刚开始⽂件指针指向的是⽂件的开头,把⽂件指针从0位置开始,移动到⽂件末尾//获取⽂件长度;length = ftell(fp);//fp指向了⽂件的末尾fseek(fp, 0L, SEEK_SET);//再把⽂件指针指向⽂件的头部if (length > 1024*8) //⽂件不能超过8K,不然内存不⽀持{rv = -3;printf("⽂件超过1024*8, nunsupport");goto End;}while (!feof(fp)){//读每⼀⾏memset(lineBuf, 0, sizeof(lineBuf));pTmp = fgets(lineBuf, MaxLine, fp);if (pTmp == NULL){break;}//key关键字是否在本⾏pTmp = strstr(lineBuf, pKey);if (pTmp == NULL) //key关键字不在本⾏, copy到filebuf中{strcat(filebuf, lineBuf);//复制到filebuf中去continue;}else//key关键在在本⾏中,替换旧的⾏,再copy到filebuf中{sprintf(lineBuf, "%s = %s\n", pKey, pValue);strcat(filebuf, lineBuf);//若存在keyiTag = 1;}}//所有的⾏中若key关键字,不存在追加if (iTag == 0){fprintf(fp, "%s = %s\n", pKey, pValue);//格式化输⼊}else//若key关键字,存在,则重新创建⽂件{if (fp != NULL){fclose(fp); //关闭⽂件fp = NULL; //避免野指针}fp = fopen(pFileName, "w+t"); //重新建⽴⼀个⽂件if (fp == NULL){rv = -4;printf("fopen() err. \n");goto End;}fputs(filebuf, fp);//把所有⽂件缓冲的内容输⼊到fp,覆盖原来的⽂件//fwrite(filebuf, sizeof(char), strlen(filebuf), fp);}End:if (fp != NULL){fclose(fp);}return rv;}#define _CRT_SECURE_NO_WARNINGS#include <stdlib.h>#include <string.h>#include <stdio.h>#include "cfg_op.h"#define CFGNAME "c:/mycfg.ini"void mymenu(){printf("=============================\n");printf("1 测试写配置⽂件\n");printf("2 测试读配置⽂件\n");printf("0 退出\n");printf("=============================\n");}//获取配置项int TGetCfg(){int ret = 0;//读配置项char name[1024] = {0};char valude[1024] = {0};int vlen = 0;printf("\n请键⼊key:");scanf("%s", name);ret = GetCfgItem(CFGNAME /*in*/, name /*in*/, valude/*in*/, &vlen);if (ret != 0){printf("func WriteCfgItem err:%d \n", ret);return ret;}printf("valude:%s \n", valude);}//写配置项int TWriteCfg(){int ret = 0;//写配置项char name[1024] = {0};char valude[1024] = {0};printf("\n请键⼊key:");scanf("%s", name);printf("\n请键⼊valude:");scanf("%s", valude);ret = WriteCfgItem(CFGNAME /*in*/, name /*in*/, valude/*in*/,strlen(valude) /*in*/); if (ret != 0){printf("func WriteCfgItem err:%d \n", ret);return ret;}printf("你的输⼊是:%s = %s \n", name , valude);return ret;}void main(){int choice;for (;;){//显⽰⼀个菜单mymenu();scanf("%d", &choice);switch (choice){case1: //写配置项TWriteCfg();break;case2:TGetCfg(); //读配置项break;case0:exit(0);default:;exit(0);}}printf("hello...\n");system("pause");return ;}。
c读取配置文件的方法在C语言中,读取配置文件是一项非常常见的任务。
配置文件通常包含了程序运行时需要的各种参数和设置,因此读取配置文件是程序启动时必须完成的任务之一。
本文将介绍如何使用C语言读取配置文件。
我们需要了解配置文件的格式。
配置文件通常是一个文本文件,其中包含了一系列的键值对。
每个键值对由一个键和一个值组成,中间用等号连接。
例如:```key1=value1key2=value2key3=value3```在C语言中,我们可以使用标准库中的fopen函数打开配置文件。
例如:```cFILE *fp = fopen("config.ini", "r");```这里我们打开了一个名为config.ini的文件,并以只读模式打开。
接下来,我们可以使用标准库中的fgets函数逐行读取配置文件。
例如:```cchar line[256];while (fgets(line, sizeof(line), fp)) {// 处理每一行}```这里我们定义了一个长度为256的字符数组line,然后使用fgets 函数逐行读取配置文件。
fgets函数的第一个参数是一个字符数组,用于存储读取到的行;第二个参数是字符数组的长度;第三个参数是文件指针,用于指定要读取的文件。
接下来,我们需要解析每一行的键值对。
我们可以使用标准库中的strtok函数将每一行按照等号分割成键和值。
例如:```cchar *key = strtok(line, "=");char *value = strtok(NULL, "=");```这里我们使用strtok函数将line按照等号分割成两个部分,分别是键和值。
strtok函数的第一个参数是要分割的字符串;第二个参数是分割符,这里是等号。
strtok函数会返回分割后的第一个部分,我们可以使用NULL作为第一个参数来获取分割后的第二个部分。
CFG、INI配置文件读写C程序/******************************************************************** * 文件名称: INIFileOP.C* 文件标识:* 其它说明: INI文件的操作* 当前版本: V1.0* 完成日期:********************************************************************* */#include#include#include/*#undef VOS_WINNT*/#define VOS_WINNT#ifdef VOS_WINNT#define INIFileTstmain main#endif#define SuccessRet 1;#define FailedRet 0;#defineMAX_CFG_BUF512#defineCFG_OK#define CFG_SECTION_NOT_FOUND-1#define CFG_KEY_NOT_FOUND -2#define CFG_ERR -10#define CFG_ERR_FILE -10#define CFG_ERR_OPEN_FILE -10#define CFG_ERR_CREATE_FILE -11#define CFG_ERR_READ_FILE -12#define CFG_ERR_WRITE_FILE -13#define CFG_ERR_FILE_FORMAT -14#define CFG_ERR_SYSTEM -20#define CFG_ERR_SYSTEM_CALL -20#define CFG_ERR_INTERNAL -21#define CFG_ERR_EXCEED_BUF_SIZE -22#define COPYF_OK 0#define COPYF_ERR_OPEN_FILE -10#define COPYF_ERR_CREATE_FILE -11#define COPYF_ERR_READ_FILE -12#define COPYF_ERR_WRITE_FILE -13#define TXTF_OK 0#define TXTF_ERR_OPEN_FILE -1#define TXTF_ERR_READ_FILE -2#define TXTF_ERR_WRITE_FILE -3#define TXTF_ERR_DELETE_FILE -4#define TXTF_ERR_NOT_FOUND -5char CFG_ssl = '[', CFG_ssr = ']';/* 项标志符Section Symbol --可根据特殊需要进行定义更改,如 { }等*/ char CFG_nis = ':'; /*name 与 index 之间的分隔符 */char CFG_nts = '#'; /*注释符*/int CFG_section_line_no, CFG_key_line_no, CFG_key_lines;static char * strtrimr(char * buf);static char * strtriml(char * buf);static int FileGetLine(FILE *fp, char *buffer, intmaxlen);static int SplitKeyValue(char *buf, char **key, char **val);extern int FileCopy(void *source_file, void *dest_file);extern int SplitSectionToNameIndex(char *section, char **name, char **index);extern int JoinNameIndexToSection(char **section, char *name, char *index);extern int ConfigGetKey(void *CFG_file, void *section, void *key, void *buf);extern int ConfigSetKey(void *CFG_file, void *section, void *key, void *buf);extern int ConfigGetSections(void *CFG_file, char *sections[]); extern int ConfigGetKeys(void *CFG_file, void *section, char *keys[]);extern void INIFileTstmain(void);/******************************************************************** *** 函数名称: strtrimr* 功能描述:去除字符串右边的空字符* 访问的表:无* 修改的表:无* 输入参数: char * buf 字符串指针* 输出参数:无* 返回值:字符串指针* 其它说明:无********************************************************************/ char * strtrimr(char * buf){intlen,i;char * tmp = NULL;len = strlen(buf);tmp = (char*)malloc(len);memset(tmp,0x00,len);for(i = 0;i <len;i++){if (buf[i] !=' ')break;}if (i<len) {strncpy(tmp,(buf+i),(len-i));}strncpy(buf,tmp,len);free(tmp);return buf;}/******************************************************************** *** 函数名称: strtriml* 功能描述:去除字符串左边的空字符* 访问的表:无* 修改的表:无* 输入参数: char * buf 字符串指针* 输出参数:无* 返回值:字符串指针* 其它说明:无********************************************************************* **/char * strtriml(char * buf){intlen,i;char * tmp=NULL;len = strlen(buf);tmp = (char*)malloc(len);memset(tmp,0x00,len);for(i = 0;i <len;i++){if (buf[len-i-1] !=' ')break;}if (i<len) {strncpy(tmp,buf,len-i);}strncpy(buf,tmp,len);free(tmp);return buf;}/******************************************************************** *** 函数名称: FileGetLine* 功能描述:从文件中读取一行* 访问的表:无* 修改的表:无* 输入参数: FILE *fp 文件句柄;intmaxlen 缓冲区最大长度* 输出参数: char *buffer 一行字符串* 返回值:实际读的长度* 其它说明:无********************************************************************* **/int FileGetLine(FILE *fp, char *buffer, intmaxlen){int i, j;char ch1;for(i = 0, j = 0; i<maxlen; j++){if(fread(&ch1, sizeof(char), 1, fp) != 1){if(feof(fp) != 0){if(j == 0) return -1; /* 文件结束 */else break;}if(ferror(fp) != 0) return -2; /* 读文件出错 */return -2;}else{if(ch1 == '\n' || ch1 == 0x00) break; /* 换行 */if(ch1 == '\f' || ch1 == 0x1A) /* '\f':换页符也算有效字符 */ {buffer[i++] = ch1;break;}if(ch1 != '\r') buffer[i++] = ch1; /* 忽略回车符 */ }}buffer[i] = '\0';return i;}/******************************************************************** *** 函数名称: FileCopy* 功能描述:文件拷贝* 访问的表:无* 修改的表:无* 输入参数: void *source_file 源文件void *dest_file 目标文件* 输出参数:无* 返回值: 0 -- OK,非0--失败* 其它说明:无********************************************************************* **/int FileCopy(void *source_file, void *dest_file){FILE *fp1, *fp2;char buf[1024+1];int ret;if((fp1 = fopen((char *)source_file, "r")) == NULL)return COPYF_ERR_OPEN_FILE;ret = COPYF_ERR_CREATE_FILE;if((fp2 = fopen((char *)dest_file, "w")) == NULL) gotocopy_end;while(1){ret = COPYF_ERR_READ_FILE;memset(buf, 0x00, 1024+1);if(fgets((char *)buf, 1024, fp1) == NULL){if(strlen(buf) == 0){if(ferror(fp1) != 0) gotocopy_end;break; /* 文件尾 */}}ret = COPYF_ERR_WRITE_FILE;if(fputs((char *)buf, fp2) == EOF) gotocopy_end;}ret = COPYF_OK;copy_end:if(fp2 != NULL) fclose(fp2);if(fp1 != NULL) fclose(fp1);return ret;}/******************************************************************** *** 函数名称: SplitSectionToNameIndex* 功能描述:分离section为name和index* [section]* / \* name:index* jack : 12* | | |* k1 k2 i* 访问的表:无* 修改的表:无* 输入参数: char *section* 输出参数: char **name, char **index* 返回值: 1 --- ok* 0 --- blank line* -1 --- no name, ":index"* -2 --- only name, no ':'* 其它说明:无********************************************************************/ int SplitSectionToNameIndex(char *section, char **name, char **index) {int i, k1, k2, n;if((n = strlen((char *)section)) < 1) return 0;for(i = 0; i< n; i++)if(section[i] != ' ' && section[i] != '\t') break;if(i>= n) return 0;if(section[i] == CFG_nis) return -1;k1 = i;for(i++; i< n; i++)if(section[i] == CFG_nis) break;if(i>= n) return -2;k2 = i;for(i++; i< n; i++)if(section[i] != ' ' && section[i] != '\t') break;section[k2] = '\0';*name = section + k1;*index = section + i;return 1;}/******************************************************************** *** 函数名称: JoinNameIndexToSection* 功能描述:合成name和indexsection为section* jack : 12* name:index* \ /* [section]* 访问的表:无* 修改的表:无* 输入参数: char *name, char *index* 输出参数: char **section* 返回值: 1 --- ok* 0 --- blank line* 其它说明:无********************************************************************/ int JoinNameIndexToSection(char **section, char *name, char *index)int n1,n2;if((n1 = strlen((char *)name)) < 1) return 0;if((n2 = strlen((char *)index)) < 1) return 0;strcat(*section,name);strcat(*section+n1,":");strcat(*section+n1+1,index);*(*section+n1+1+n2) = '\0';return 1;}/******************************************************************** *** 函数名称: SplitKeyValue* 功能描述:分离key和value* key=val* jack = liaoyuewang* | | |* k1 k2 i* 访问的表:无* 修改的表:无* 输入参数: char *buf* 输出参数: char **key;char **val* 返回值: 1 --- ok* 0 --- blank line* -1 --- no key, "= val"* -2 --- only key, no '='* 其它说明:无********************************************************************/ int SplitKeyValue(char *buf, char **key, char **val){int i, k1, k2, n;if((n = strlen((char *)buf)) < 1) return 0;for(i = 0; i< n; i++)if(buf[i] != ' ' &&buf[i] != '\t') break;if(i>= n) return 0;if(buf[i] == '=') return -1;k1 = i;for(i++; i< n; i++)if(buf[i] == '=') break;if(i>= n) return -2;k2 = i;for(i++; i< n; i++)if(buf[i] != ' ' &&buf[i] != '\t') break;buf[k2] = '\0';*key = buf + k1;*val = buf + i;return 1;}/******************************************************************** *** 函数名称: ConfigGetKey* 功能描述:获得key的值* 访问的表:无* 修改的表:无* 输入参数: void *CFG_file 文件;void *section 项值;void *key 键值* 输出参数: void *buf key的值* 返回值: 0 --- ok 非0 --- error* 其它说明:无********************************************************************/ int ConfigGetKey(void *CFG_file, void *section, void *key, void *buf) {FILE *fp;char buf1[MAX_CFG_BUF + 1], buf2[MAX_CFG_BUF + 1];char *key_ptr, *val_ptr;int line_no, n, ret;line_no = 0;CFG_section_line_no = 0;CFG_key_line_no = 0;CFG_key_lines = 0;if((fp = fopen((char *)CFG_file, "rb")) == NULL) returnCFG_ERR_OPEN_FILE;while(1) /* 搜找项section */{ret = CFG_ERR_READ_FILE;n = FileGetLine(fp, buf1, MAX_CFG_BUF);if(n < -1) gotor_cfg_end;ret = CFG_SECTION_NOT_FOUND;if(n < 0) gotor_cfg_end; /* 文件尾,未发现 */line_no++;n = strlen(strtriml(strtrimr(buf1)));if(n == 0 || buf1[0] == CFG_nts) continue; /* 空行或注释行 */ ret = CFG_ERR_FILE_FORMAT;if(n > 2 && ((buf1[0] == CFG_ssl&& buf1[n-1] != CFG_ssr))) gotor_cfg_end;if(buf1[0] == CFG_ssl){buf1[n-1] = 0x00;if(strcmp(buf1+1, section) == 0)break; /* 找到项section */}}CFG_section_line_no = line_no;while(1) /* 搜找key */{ret = CFG_ERR_READ_FILE;n = FileGetLine(fp, buf1, MAX_CFG_BUF);if(n < -1) gotor_cfg_end;ret = CFG_KEY_NOT_FOUND;if(n < 0) gotor_cfg_end; /* 文件尾,未发现key */line_no++;CFG_key_line_no = line_no;CFG_key_lines = 1;n = strlen(strtriml(strtrimr(buf1)));if(n == 0 || buf1[0] == CFG_nts) continue; /* 空行或注释行 */ ret = CFG_KEY_NOT_FOUND;if(buf1[0] == CFG_ssl) gotor_cfg_end;if(buf1[n-1] == '+') /* 遇+号表示下一行继续 */ {buf1[n-1] = 0x00;while(1){ret = CFG_ERR_READ_FILE;n = FileGetLine(fp, buf2, MAX_CFG_BUF);if(n < -1) gotor_cfg_end;if(n < 0) break; /* 文件结束 */line_no++;CFG_key_lines++;n = strlen(strtrimr(buf2));ret = CFG_ERR_EXCEED_BUF_SIZE;if(n > 0 && buf2[n-1] == '+') /* 遇+号表示下一行继续 */ {buf2[n-1] = 0x00;if(strlen(buf1) + strlen(buf2) > MAX_CFG_BUF)gotor_cfg_end;strcat(buf1, buf2);continue;}if(strlen(buf1) + strlen(buf2) > MAX_CFG_BUF)gotor_cfg_end;strcat(buf1, buf2);break;}}ret = CFG_ERR_FILE_FORMAT;if(SplitKeyValue(buf1, &key_ptr, &val_ptr) != 1)gotor_cfg_end;strtriml(strtrimr(key_ptr));if(strcmp(key_ptr, key) != 0)continue;/* 和key值不匹配 */strcpy(buf, val_ptr);break;}ret = CFG_OK;r_cfg_end:if(fp != NULL) fclose(fp);return ret;}/******************************************************************** *** 函数名称: ConfigSetKey* 功能描述:设置key的值* 访问的表:无* 修改的表:无* 输入参数: void *CFG_file 文件;void *section 项值;* void *key 键值;void *buf key的值* 输出参数:无* 返回值: 0 --- ok 非0 --- error* 其它说明:无********************************************************************/ int ConfigSetKey(void *CFG_file, void *section, void *key, void *buf) {FILE *fp1, *fp2;char buf1[MAX_CFG_BUF + 1];int line_no, line_no1, n, ret, ret2;char *tmpfname;ret = ConfigGetKey(CFG_file, section, key, buf1);if(ret <= CFG_ERR && ret != CFG_ERR_OPEN_FILE) return ret;if(ret == CFG_ERR_OPEN_FILE || ret == CFG_SECTION_NOT_FOUND) {if((fp1 = fopen((char *)CFG_file, "a")) == NULL)return CFG_ERR_CREATE_FILE;if(fprintf(fp1, "%c%s%c\n", CFG_ssl, section, CFG_ssr) == EOF) {fclose(fp1);return CFG_ERR_WRITE_FILE;}if(fprintf(fp1, "%s=%s\n", key, buf) == EOF){fclose(fp1);return CFG_ERR_WRITE_FILE;}fclose(fp1);return CFG_OK;}if((tmpfname = tmpnam(NULL)) == NULL)return CFG_ERR_CREATE_FILE;if((fp2 = fopen(tmpfname, "w")) == NULL)return CFG_ERR_CREATE_FILE;ret2 = CFG_ERR_OPEN_FILE;if((fp1 = fopen((char *)CFG_file, "rb")) == NULL) gotow_cfg_end;if(ret == CFG_KEY_NOT_FOUND)line_no1 = CFG_section_line_no;else /* ret = CFG_OK */line_no1 = CFG_key_line_no - 1;for(line_no = 0; line_no< line_no1; line_no++){ret2 = CFG_ERR_READ_FILE;n = FileGetLine(fp1, buf1, MAX_CFG_BUF);if(n < 0) gotow_cfg_end;ret2 = CFG_ERR_WRITE_FILE;if(fprintf(fp2, "%s\n", buf1) == EOF) gotow_cfg_end;}if(ret != CFG_KEY_NOT_FOUND)for( ; line_no< line_no1+CFG_key_lines; line_no++){ret2 = CFG_ERR_READ_FILE;n = FileGetLine(fp1, buf1, MAX_CFG_BUF);if(n < 0) gotow_cfg_end;}ret2 = CFG_ERR_WRITE_FILE;if(fprintf(fp2, "%s=%s\n", key, buf) == EOF) gotow_cfg_end;while(1){ret2 = CFG_ERR_READ_FILE;n = FileGetLine(fp1, buf1, MAX_CFG_BUF);if(n < -1) gotow_cfg_end;if(n < 0) break;ret2 = CFG_ERR_WRITE_FILE;if(fprintf(fp2, "%s\n", buf1) == EOF) gotow_cfg_end;}ret2 = CFG_OK;w_cfg_end:if(fp1 != NULL) fclose(fp1);if(fp2 != NULL) fclose(fp2);if(ret2 == CFG_OK){ret = FileCopy(tmpfname, CFG_file);if(ret != 0) return CFG_ERR_CREATE_FILE;}remove(tmpfname);return ret2;}/******************************************************************** *** 函数名称: ConfigGetSections* 功能描述:获得所有section* 访问的表:无* 修改的表:无* 输入参数: void *CFG_file 文件* 输出参数: char *sections[] 存放section名字* 返回值:返回section个数。