用 C parse INI 配置檔案
用 C parse INI 配置檔案,讀取 VAL 值
一、ini配置檔案的格式
為什麼要用INI檔案?如果我們程式沒有任何配置檔案時,這樣的程式對外是全封閉的,一旦程式需要修改一些引數必須要修改程式程式碼本身並重新編譯,這樣很不好,所以要用配置檔案,讓程式釋出後還能根據需要進行必要的配置;配置檔案有很多如INI配置檔案,XML配置檔案,還有就是可以使用系統登錄檔等。
本文主要是為讀者在實現讀寫INI配置檔案模組之前,提供有關INI檔案的格式資訊。在早期的windows桌面系統中主要是用INI檔案作為系統的配置檔案,從win95以後開始轉向使用登錄檔,但是還有很多系統配置是使用INI檔案的。其實INI檔案就是簡單的text檔案,只不過這種txt檔案要遵循一定的INI檔案格式。現在的WINCE系統上也常常用INI檔案作為配置檔案,這次研究INI檔案的目的就是為了 給我的對接報警服務程式新增配置檔案。“.INI ”就是英文 “initialization”的頭三個字母的縮寫;當然INI file的字尾名也不一定是".ini"也可以是".cfg",".conf ”或者是".txt"。
1、INI檔案由節、鍵、值組成。
節
[section]
引數(鍵=值)
name=value
註解
註解使用分號表示(;)。在分號後面的文字,直到該行結尾都全部為註解。
2、INI檔案的格式很簡單,最基本的三個要素是:sections,parameters和comments。
什麼是sections ?
所有的parameters都是以sections為單位結合在一起的。所有的section名稱都是獨佔一行,並且sections名字都被方括號包圍著([ and ])。在section聲明後的所有parameters都是屬於該section。對於一個section沒有明顯的結束標誌符,一個section的開始就是上一個section的結束,或者是end of the file。Sections一般情況下不能被nested,當然特殊情況下也可以實現sections的巢狀。
section如下所示:
[section]
什麼是parameters?
INI所包含的最基本的“元素”就是parameter;每一個parameter都有一個name和一個value,name和value是由等號“=”隔開。name在等號的左邊。
例子如下:
name = value
什麼是comments?
在INI檔案中註釋語句是以分號“;”開始的。所有的所有的註釋語句不管多長都是獨佔一行直到結束的,在分號和行結束符之間的所有內容都是被忽略的。
註釋例項如下:
;comments text
參考文章:
https://blog.csdn.net/chexlong/article/details/6818017
二、程式碼參考如下:
1 #defineCONF_FILE_PATH "Config.ini" 2 3 #include <string.h> 4 5 #ifdef WIN32 6 #include <Windows.h> 7 #include <stdio.h> 8 #else 9 10 #define MAX_PATH 260 11 12 #include <unistd.h> 13 #include <fcntl.h> 14 #include <stdio.h> 15 #include <stdlib.h> 16 #include <stdarg.h> 17 #endif 18 19 char g_szConfigPath[MAX_PATH]; 20 21 //獲取當前程式目錄 22 int GetCurrentPath(char buf[],char *pFileName) 23 { 24 #ifdef WIN32 25 GetModuleFileName(NULL,buf,MAX_PATH); 26 #else 27 char pidfile[64]; 28 int bytes; 29 int fd; 30 31 sprintf(pidfile, "/proc/%d/cmdline", getpid()); 32 33 fd = open(pidfile, O_RDONLY, 0); 34 bytes = read(fd, buf, 256); 35 close(fd); 36 buf[MAX_PATH] = '\0'; 37 38 #endif 39 char * p = &buf[strlen(buf)]; 40 do 41 { 42 *p = '\0'; 43 p--; 44 #ifdef WIN32 45 } while( '\\' != *p ); 46 #else 47 } while( '/' != *p ); 48 #endif 49 50 p++; 51 52 //配置檔案目錄 53 memcpy(p,pFileName,strlen(pFileName)); 54 return 0; 55 } 56 57 //從INI檔案讀取字串型別資料 58 char *GetIniKeyString(char *title,char *key,char *filename) 59 { 60 FILE *fp; 61 char szLine[1024]; 62 static char tmpstr[1024]; 63 int rtnval; 64 int i = 0; 65 int flag = 0; 66 char *tmp; 67 68 if((fp = fopen(filename, "r")) == NULL) 69 { 70 printf("have no such file \n"); 71 return ""; 72 } 73 while(!feof(fp)) 74 { 75 rtnval = fgetc(fp); 76 if(rtnval == EOF) 77 { 78 break; 79 } 80 else 81 { 82 szLine[i++] = rtnval; 83 } 84 if(rtnval == '\n') 85 { 86 #ifndef WIN32 87 i--; 88 #endif 89 szLine[--i] = '\0'; 90 i = 0; 91 tmp = strchr(szLine, '='); 92 93 if(( tmp != NULL )&&(flag == 1)) 94 { 95 if(strstr(szLine,key)!=NULL) 96 { 97 //註釋行 98 if ('#' == szLine[0]) 99 { 100 } 101 else if ( '\/' == szLine[0] && '\/' == szLine[1] ) 102 { 103 104 } 105 else 106 { 107 //找打key對應變數 108 strcpy(tmpstr,tmp+1); 109 fclose(fp); 110 return tmpstr; 111 } 112 } 113 } 114 else 115 { 116 strcpy(tmpstr,"["); 117 strcat(tmpstr,title); 118 strcat(tmpstr,"]"); 119 if( strncmp(tmpstr,szLine,strlen(tmpstr)) == 0 ) 120 { 121 //找到title 122 flag = 1; 123 } 124 } 125 } 126 } 127 fclose(fp); 128 return ""; 129 } 130 131 //從INI檔案讀取整型別資料 132 int GetIniKeyInt(char *title,char *key,char *filename) 133 { 134 return atoi(GetIniKeyString(title,key,filename)); 135 } 136 137 int main(int argc, char* argv[]) 138 { 139 char buf[MAX_PATH]; 140 memset(buf,0,sizeof(buf)); 141 GetCurrentPath(buf,CONF_FILE_PATH); 142 strcpy(g_szConfigPath,buf); 143 144 int iCatAge; 145 char szCatName[32]; 146 147 iCatAge = GetIniKeyInt("CAT","age",g_szConfigPath); 148 strcpy(szCatName,GetIniKeyString("CAT","name",g_szConfigPath)); 149 150 return 0; 151 }
Config.ini 檔案:
[CAT] age = 2 name = Tom