INI文件的讀取(C語言:GetPrivateProfileString/GetPrivateProfileInt)


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 }
dupFile

 

下面代碼注釋中寫的不區分大小寫是不對的,是區分大小寫的。

/*函數說明:從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 }
GetPrivateProfileString

 

 

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 }
GetPrivateProfileInt

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM