INI文件格式說明
/********************************************* ini文件說明 ini文件是文本文件,由節點(Section)和鍵值對(key=value)組成 以';'開頭的行為注釋 一般形式如下所示: +--------------- test.ini -----------------+ | [Section1] | | key1=value1 | | key2=value2 | | ;這是注釋 | | [Section2] | | key3=value3 | +------------------------------------------+ *********************************************/
更詳細的介紹可見http://blog.chinaunix.net/uid-25885064-id-3327199.html
GetPrivateProfileString 從INI文件中讀取String值
輔助函數 dupFile

1 //讀取文件內容,保存到在heap區上申請的內存中 2 //成功返回內存地址,失敗返回NULL 3 //參數fsize用於傳出文件的內存區域的大小 4 char* dupFile(const char* FileName,long* fsize) 5 { 6 char* buf = NULL; 7 long size = 0; 8 //讀取文件,因為ini文件通常都很小,所以一次全部讀取了 9 FILE* fp = fopen(FileName,"r"); 10 do{ 11 if(fp == NULL){ //打開文件失敗 12 //puts("打開文件失敗"); 13 break; 14 } 15 //獲取文件大小 16 if(fseek(fp,0,SEEK_END)){ 17 break; //fseek失敗 18 } 19 size = ftell(fp); //獲取當前偏移(文件長度) 20 if(size<0){break;} 21 22 //讀取文件 23 fseek(fp,0,SEEK_SET); 24 buf = (char*)malloc(size+1); 25 if(buf == NULL){break;} 26 if(size == fread(buf,1,size,fp)){ //fread是阻塞模式,= 27 buf[size] = '\0'; 28 //文件已經讀取完成了 29 }else{ //萬一失敗了呢? 30 free(buf); 31 buf = NULL; 32 size = 0; 33 } 34 }while(0); 35 fclose(fp); //關閉文件 36 if(fsize != NULL){*fsize = size;} 37 return buf; 38 }
下面代碼注釋中寫的不區分大小寫是不對的,是區分大小寫的。
/*函數說明:從FileName指定的ini文件中讀取section節點下key鍵對應的value值(字符串)
*參數說明: Section: 節點名(不區分大小寫)
* Key: 鍵名(不區分大小寫)
* Default: 沒有找到對應的value時的默認值
* ReturnedString: 接收找到的value的緩沖區
* nSize: 緩沖區的大小
* FileName: ini文件路徑
*返回值:讀取成功返回讀取到的value的字符數。如果緩沖區不夠大,value會被截斷,返回nSize-1
*/

1 /*函數說明:從FileName指定的ini文件中讀取section節點下key鍵對應的value值(字符串) 2 *參數說明: Section: 節點名(不區分大小寫) 3 * Key: 鍵名(不區分大小寫) 4 * Default: 沒有找到對應的value時的默認值 5 * ReturnedString: 接收找到的value的緩沖區 6 * nSize: 緩沖區的大小 7 * FileName: ini文件路徑 8 *返回值:讀取成功返回讀取到的value的字符數。如果緩沖區不夠大,value會被截斷,返回nSize-1 9 */ 10 11 unsigned long GetPrivateProfileString( 12 const char* Section, //節點 13 const char* Key, //鍵 14 const char* Default, //默認值 15 char* ReturnedString, //接收獲取值的目標緩沖區 16 unsigned long nSize, //目標緩沖區大小 17 const char* FileName //ini文件路徑 18 ) 19 { 20 FILE* fp; //文件指針 21 long fsize; //文件大小 22 long len; // 23 char* buf; //用於保存文件內容 24 char* psec; //保存節點位置 25 char* pkey; //指向文件中key位置 26 char* pval; //指向文件中value的位置 27 int iscomment; //用於判讀是否是注釋 28 do{ 29 //獲取文件內容 30 buf = dupFile(FileName,&fsize); 31 if(buf == NULL){break;} 32 33 //查找節點位置 34 char sbuf[1024]; 35 sprintf(sbuf,"[%s]",Section); 36 psec = strstr(buf,sbuf); //查找節點 37 if(psec == NULL){ 38 printf("沒有找到節點 %s \n",sbuf); 39 break;//沒有找到節點 40 } 41 //尋找key 42 pkey = psec; //查找的起點 43 44 //查找key 45 while((pkey = strstr(pkey,Key))!= NULL){ 46 //找到了匹配的,進入 47 //判斷找到的key是否與傳入的一致(避免傳入的是找到的前綴) 48 //如傳入 "abc" 找到的是 "abcdef\n" 49 len = strlen(Key); 50 pval =pkey + len; //用pval指向pkey的尾部 51 char t = pval[0]; 52 if(t == '=' || t==' ' || t=='\t'){ 53 break; //找到了key,跳出本while 54 } 55 //沒有找到key,去查找下一個匹配的 56 }// end while 57 if(pkey == NULL){ 58 printf("沒有找到Key:%s\n",Key); 59 break; //沒有找到key,跳出 60 } 61 //確定找到的key是當前節點的(查找key和當前節點之間還有無節點) 62 pkey[-1] = '\0'; //從找到的key前截斷 63 psec = strchr(psec,']') +1; //當前節點之后開始找 64 while((psec=strchr(psec,'[')) != NULL){ 65 //判斷該行是否是注釋 66 char* pt = psec++; //psec指向'['的下一個去 67 while(*(--pt) != ';'&& *pt != '\n'); 68 if(*pt == ';'){ continue;}//是注釋,下一個 69 //不是注釋,判斷是否是合法節點([]存在,有內容且在同一行) 70 pt = psec; 71 while(*(++pt) != ']' && *pt != '\n'); 72 if(*pt==']'){//當前行有']'來閉合,說明Section和Key之間還有節點 73 pval = NULL; //設置為NULL,表示不用找了 74 break; 75 } 76 }//end while 77 if(pval == NULL){ 78 break; //找到的key不是傳入Section下的 79 } 80 81 //確定了找到的key確實與傳入的一致,查找value位置 82 while(*pval != '=' && *pval != '\n' && *pval != '\0'){ 83 ++pval; //查找'='的位置(key=value必須在一行) 84 } 85 if(*pval != '='){break;} //沒有找到value 86 ++pval; //現在pkey指向value(可能用空白,使用sscanf來去除) 87 // 找到 value 的情況,僅此一處 88 if((fsize - (pval - buf) - nSize) > 0){ 89 pval[nSize-1] = '\0'; //避免value太長 90 } 91 len = sscanf(pval,"%s",ReturnedString); //sscanf %s 遇到空格\n\t\0都結束 92 free(buf); //釋放buf 93 return len; //返回拷貝的長度 94 95 //結束查找 96 }while(0); 97 98 //沒有找到的情況 99 strncpy(ReturnedString,Default,nSize-1); 100 ReturnedString[nSize-1] = '\0'; 101 free(buf); //釋放buf 102 return strlen(ReturnedString); 103 }
GetPrivateProfileInt從INI文件中讀取Int值

1 /*函數說明:從FileName指定的ini文件中讀取section節點下key鍵對應的value值(整型數) 2 *參數說明: Section: 節點名(不區分大小寫) 3 * Key: 鍵名(不區分大小寫) 4 * Default: 沒有找到對應的value時的默認值 5 * FileName: ini文件路徑 6 *返回值:讀取成功返回找到的value值。沒找到就返回Default 7 */ 8 9 int GetPrivateProfileInt( 10 const char* Section, // 指向包含 Section 名稱的字符串地址 11 const char* Key, // 指向包含 Key 名稱的字符串地址 12 int Default, // 如果 Key 值沒有找到,則返回缺省的值是多少 13 const char* FileName // ini 文件的文件名 14 ) 15 { 16 char buf[1024]; 17 sprintf(&buf[512],"%d",Default); //獲取默認值 18 GetPrivateProfileString(Section,Key,&buf[512],buf,512,FileName); 19 return atoi(buf); 20 }