zoukankan      html  css  js  c++  java
  • 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] = '';
    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 
    ",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
    "
     49             len = strlen(Key);
     50             pval =pkey + len;    //用pval指向pkey的尾部
     51             char t = pval[0];
     52             if(t == '=' || t==' ' || t=='	'){
     53                 break;    //找到了key,跳出本while
     54             }
     55             //没有找到key,去查找下一个匹配的
     56         }// end while
     57         if(pkey == NULL){
     58             printf("没有找到Key:%s
    ",Key);
     59             break;    //没有找到key,跳出
     60         }
     61         //确定找到的key是当前节点的(查找key和当前节点之间还有无节点)
     62         pkey[-1] = '';    //从找到的key前截断
     63         psec = strchr(psec,']') +1;    //当前节点之后开始找
     64         while((psec=strchr(psec,'[')) != NULL){
     65             //判断该行是否是注释
     66             char* pt = psec++;    //psec指向'['的下一个去
     67             while(*(--pt) != ';'&& *pt != '
    ');
     68             if(*pt == ';'){    continue;}//是注释,下一个
     69             //不是注释,判断是否是合法节点([]存在,有内容且在同一行)
     70             pt = psec;
     71             while(*(++pt) != ']' && *pt != '
    ');
     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 != '
    ' && *pval != ''){
     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] = '';    //避免value太长
     90         }
     91         len = sscanf(pval,"%s",ReturnedString);    //sscanf %s 遇到空格
    	都结束
     92         free(buf);    //释放buf
     93         return len;    //返回拷贝的长度
     94 
     95         //结束查找
     96     }while(0);
     97 
     98     //没有找到的情况
     99     strncpy(ReturnedString,Default,nSize-1);
    100     ReturnedString[nSize-1] = '';
    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
  • 相关阅读:
    Java学习个人备忘录之继承
    Java学习个人备忘录之文档注释
    Java学习个人备忘录之数组工具类
    Java学习个人备忘录之关键字static
    Java学习个人备忘录之构造函数&this
    Java学习个人备忘录之面向对象概念
    Java学习个人备忘录之数组
    Java学习个人备忘录之入门基础
    hdoj1162-Eddy's picture(kruskal)
    hdoj1102-Constructing Roads(Kruskal)
  • 原文地址:https://www.cnblogs.com/oloroso/p/4630120.html
Copyright © 2011-2022 走看看