纯C读写ini文件

// C读写ini文件
// 转至:http://blog.csdn.net/chinayaosir/article/details/3613111

/*
read/write ini file with c function
@file testini.c
chinayaosir 
blog:    http://blog.csdn.net/chinayaosir
connect.ini
[database]
此程序有些BUG
当ini文件不存在时,第一次建立connect.ini文件时,
在[database]前面会多一个空格.
*/
#include  "stdio.h"
#include  "inifile.h"
#define  BUF_SIZE 256


int  main()
{
    const char  * file = "connect.ini";  
    char  severname[BUF_SIZE] = {0};
    int   port=0;

    printf( "1. write/read ini file testting .../n" );   
    
    printf( "2. write data into ini file.../n" );
    
    if (! write_profile_string("database", "sever" , "192.168.1.2",file)) 
        
    {    printf( "2.1 server write %s file fail/n",file );    }
     else
    {
        printf( "2.1 server write %s file ok/n",file );
    }
    if (! write_profile_string("database", "port" , "5000",file))
    {    printf( "2.2 port write %s file fail/n",file );    }
     else
    {
        printf( "2.2 port write %s file ok/n",file );
    }

    printf( "3. read data from ini file.../n" ); 

    if ( ! read_profile_string("database", "sever", severname,BUF_SIZE,file))
        {   printf( "3.1 sever read  %s file fail/n",file );    }
    else
        {    printf( "3.1 sever = %s/n" ,severname);}

    if ( ! read_profile_int("database", "port", port,file))
        {   printf( "3.2 port read %s file fail/n",file );  }
    else
    {    port=read_profile_int("database", "port", port,file);    
        printf( "3.2 port = %d/n" ,port);
    }    

     return   0 ;

}

/*
run value:
1. write/read ini file testting ...
2. write data into ini file...
2.1 server write connect.ini file ok
2.2 port write connect.ini file ok
3. read data from ini file...
3.1 sever = 192.168.1.2
3.2 port = 5000
*/

/
/* *
*@file        inifile.h
*@cpright     (C)2007 GEC 
*@auther      dengyangjun
*@email       dyj057@gmail.com
*@version     0.1
*@create      2007-1-14 
*@modify      2007-1-14
*@brief       declare ini file operation
*@note
*@history    
*/

#ifndef INI_FILE_H_
#define  INI_FILE_H_

#ifdef __cplusplus
extern   " C "
{
#endif

int  read_profile_string(const char * section,const char * key,char * value,int  size,const char * file);
int  read_profile_int( const   char * section,const char * key, int default_value,const char * file);
int  write_profile_string(const char   * section,const char * key,const  char * value,  const char * file);

#ifdef __cplusplus
};  // end of extern "C" {
#endif

#endif   // end of INI_FILE_H_

//
/* *
*@file          inifile.c
*@cpright       (C)2007 GEC
*@auther        dengyangjun
*@email         dyj057@gmail.com
*@version       0.1
*@create        2007-1-14 
*@modify        2007-1-14
*@brief         implement ini file operation
*@note
*@history    
*/
#include  <stdio.h>
#include  <stdlib.h>
#include  <assert.h>
#include  <string.h>
#include  <ctype.h>

#include  "inifile.h"

#ifdef __cplusplus
extern   " C "
{
#endif

#define  MAX_FILE_SIZE 8096

#define  LEFT_BRACE '['
#define  RIGHT_BRACE ']'

static int load_ini_file(const  char * file,  char * buf, int * file_size)
{
    int  i = 0 ;
    FILE  * in = NULL;
    *file_size = 0 ;
    assert(file  != NULL);
    assert(buf  != NULL);

    in   =  fopen(file, "r" );
    if ( NULL  == in ) {
         return   0 ;
    }

     // load initialization file
     while ((buf[i] = fgetc(in)) != EOF) {
        i ++ ;
        assert( i < MAX_FILE_SIZE);  // file too big
    }
    
    buf[i] = '/0' ;
    *file_size  =  i;

    fclose(in);
    return   1 ;
}

/*
*<summary></summary>
* <returns>Result of the addtion(int)</returns>
* <param name="x"></param>
* <param name="y"></param>
*/

static  int isnewline( char  c)
{
     return  ( '/n'   ==  c  ||    '/r'   ==  c ) ?  1  :  0 ;
}
static   int  isend( char  c)
{
     return   '/0' == c ?  1  :  0 ;
}
static   int  isleftbarce( char  c)
{
     return  LEFT_BRACE  ==  c ?   1  :  0 ;
}
static   int  isrightbrace( char  c )
{
     return  RIGHT_BRACE  ==  c ?   1  :  0 ;
}

static  int  parse_file(const   char   * section,  
                        const   char   * key,  
                        const   char   * buf, 
                        int   * sec_s, 
                        int   * sec_e,
                        int   * key_s, 
                        int   * key_e,  
                        int   * value_s,  
                        int   * value_e)
{
     const   char   * p  =  buf;
     int  i = 0 ;

    assert(buf != NULL);
    assert(section  !=  NULL  &&  strlen(section));
    assert(key  !=  NULL  &&  strlen(key));

     * sec_e  =   * sec_s  =   * key_e  =   * key_s  =   * value_s  =   * value_e  =   - 1 ;

     while (  ! isend(p[i]) )
    {
         // find the section
         if ( (  0 == i  ||   isnewline(p[i - 1 ]) )  &&  isleftbarce(p[i]) )
        {
             int  section_start = i + 1 ;

             // find the ']'
             do
            {
                i ++ ;
            } while (  ! isrightbrace(p[i])  &&   ! isend(p[i]));

             if (  0   ==  strncmp(p + section_start,section, i - section_start))
            {
                 int  newline_start = 0 ;

                i ++ ;

                 // Skip over space char after ']'
                 while (isspace(p[i]))
                {
                    i ++ ;
                }

                 // find the section
                 * sec_s  =  section_start;
                 * sec_e  =  i;

                 while (  !  (isnewline(p[i - 1 ])  &&  isleftbarce(p[i]))  &&   ! isend(p[i]) )
                {
                     int  j = 0 ;
                     // get a new line
                    newline_start  =  i;

                     while (  ! isnewline(p[i])  &&    ! isend(p[i]) )
                    {
                        i ++ ;
                    }
                     // now i  is equal to end of the line

                    j = newline_start;

                     if ( ';'   !=  p[j])  // skip over comment
                    {
                         while (j  <  i  &&  p[j] != '=' )
                        {
                            j ++ ;
                             if ( '='   ==  p[j])
                            {
                                 if (strncmp(key,p + newline_start,j - newline_start) == 0 )
                                {
                                     // find the key ok
                                     * key_s  =  newline_start;
                                     * key_e  =  j - 1 ;

                                     * value_s  =  j + 1 ;
                                     * value_e  =  i;

                                     return   1 ;
                                }
                            }
                        }
                    }

                    i ++ ;
                }
            }
        }
         else
        {
            i ++ ;
        }
    }
     return   0 ;
}

/* *
* @brief read_profile_string <d>retrieves a string from the specified section in an initialization file.
* @param section  <t>const char * <in> <d>name of the section containing the key name.
* @param key  <t>const char *  <in><d>the name of the key whose associated string is to be retrieved.
* @param value <t>char * <out><d>pointer to the buffer that receives the retrieved string.      
* @return <t>int  <n>1 : read success; 0 : read fail.
*/       
int  read_profile_string(
                         const   char   * section,  
                         const   char   * key, 
                         char   * value,   
                         int  size,  
                         const   char   * file)
{
     char  buf[MAX_FILE_SIZE] = { 0 };
     int  file_size;
     int  sec_s,sec_e,key_s,key_e, value_s, value_e;

     // check parameters
    assert(section  !=  NULL  &&  strlen(section));
    assert(key  !=  NULL  &&  strlen(key));
    assert(value  !=  NULL);
    assert(size  >   0 );
    assert(file  != NULL  && strlen(key));

     if (  ! load_ini_file(file,buf, & file_size))
         return   0 ;

     if ( ! parse_file(section,key,buf, & sec_s, & sec_e, & key_s, & key_e, & value_s, & value_e))
    {
         return   0 ;  // not find the key
    }
     else
    {
         int  cpcount  =  value_e  - value_s;

         if ( size - 1   <  cpcount)
        {
            cpcount  =   size - 1 ;
        }
    
        memset(value,  0 , size);
        memcpy(value,buf + value_s, cpcount );
        value[cpcount]  =   '/0' ;

         return   1 ;
    }
}


int  read_profile_int(const  char *section,
                      const  char  *key, 
                      int default_value,  
                      const char *file)
{
     char  value[ 32 ]  =  { 0 };
     if ( ! read_profile_string(section,key,value,  sizeof (value),file))
    {
         return  default_value;
    }
     else
    {
         return  atoi(value);
    }
}

int  write_profile_string(const   char   * section,  
                          const   char   * key, 
                          const   char   * value,  
                          const   char   * file)
{
     char  buf[MAX_FILE_SIZE] = { 0 };
     char  w_buf[MAX_FILE_SIZE] = { 0 };
     int  sec_s,sec_e,key_s,key_e, value_s, value_e;
     int  value_len  =  ( int )strlen(value);
     int  file_size;
     FILE  * out ;

     // check parameters
    assert(section  !=  NULL  &&  strlen(section));
    assert(key  !=  NULL  &&  strlen(key));
    assert(value  !=  NULL);
    assert(file  != NULL  && strlen(key));

     if (!load_ini_file(file,buf, & file_size))
    {
        sec_s  =   - 1 ;
    }
     else
    {
        parse_file(section,key,buf, & sec_s, & sec_e, & key_s, & key_e, & value_s, & value_e);
    }

     if (  - 1   ==  sec_s)
    {
        
         if ( 0 == file_size)
        {
            sprintf(w_buf + file_size, " [%s]/n%s=%s/n" ,section,key,value);
        }
         else
        {
             // not find the section, then add the new section at end of the file
            memcpy(w_buf,buf,file_size);
            sprintf(w_buf + file_size, "/n[%s]/n%s=%s/n" ,section,key,value);
        }
        
        
    }
     else   if ( - 1   ==  key_s)
    {
         // not find the key, then add the new key & value at end of the section
        memcpy(w_buf,buf,sec_e);
        sprintf(w_buf + sec_e, "%s=%s/n" ,key,value);
        sprintf(w_buf + sec_e + strlen(key) + strlen(value) + 2 ,buf + sec_e, file_size  -  sec_e);
    }
     else
    {
         // update value with new value
        memcpy(w_buf,buf,value_s);
        memcpy(w_buf + value_s,value, value_len);
        memcpy(w_buf + value_s + value_len, buf + value_e, file_size  -  value_e);
    }
    
     out   =  fopen(file, "w" );
     if (NULL  ==   out )
    {
         return   0 ;
    }
    
     if ( - 1   ==  fputs(w_buf, out ) )
    {
        fclose( out );
         return   0 ;
    }

    fclose( out );
    
     return   1 ;
}


#ifdef __cplusplus
};  // end of extern "C" {
#endif 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
c读写ini配置文件 用c/c++读写ini配置文件有不少第三方的开源库,如iniparser、libini、rwini、UltraLightINIParser等,但都不理想,往往代码较大、功能较弱、 接口使用不方便。尤其在大小写处理、前后空格、各种注释、跨平台换行符支持、带引号字符串处理、无section操作、原格式保持等方面存在问题。 现将本人精心制作的ini读写程序源码奉献给大家,c编写,简洁好用。支持windows和linux。 主要特点: 1、支持;和#注释符号,支持行尾注释。 2、支持带引号'或"成对匹配的字符串,提取时自动去引号。引号中可带其它引号或;#注释符。 3、支持无section或空section(名称为空)。 4、支持10、16、8进制数,0x开头为16进制数,0开头为8进制。 5、支持section、key或=号前后带空格。 6、支持\n、\r、\r\n或\n\r换行格式。 7、不区分section、key大小写,但写入时以新串为准,并保持其大小写。 8、新增数据时,若section存在则在该节最后一个有效数据后添加,否则在文件尾部添加。 9、支持指定key所在整行删除,即删除该键值,包括注释。 10、可自动跳过格式错误行,修改时仍然保留。 11、修改时保留原注释:包括整行注释、行尾注释(包括前面空格)。 12、修改时保留原空行。以上三点主要是尽量保留原格式。 不足之处: 1、不支持单key多value(逗号分割),只能一次性提取后自行处理。 2、不支持同名重复section和key。(重复section可视为错误,重复key则可能造成分歧) 3、不能提取所有section或key名称。 使用只需两个文件inirw.h、inirw.c,另有测试程序和工程文件,支持windows和linux。
以下是使用C语言读写ini文件的示例代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAX_LINE_SIZE 1024 // 定义一个结构体,用于存储读取到的ini文件中的键值对 typedef struct { char key[MAX_LINE_SIZE]; char value[MAX_LINE_SIZE]; } KeyValue; // 定义一个函数,用于去除字符串两端的空格和换行符 void trim(char *str) { int len = strlen(str); while (len > 0 && (str[len - 1] == ' ' || str[len - 1] == '\n' || str[len - 1] == '\r')) { str[--len] = '\0'; } int start = 0; while (str[start] && (str[start] == ' ' || str[start] == '\n' || str[start] == '\r')) { ++start; } if (start > 0) { memmove(str, str + start, len - start + 1); } } // 定义一个函数,用于读取ini文件中的键值对 int read_ini_file(const char *filename, KeyValue *kv, int max_count) { FILE *fp = fopen(filename, "r"); if (fp == NULL) { return -1; } int count = 0; char line[MAX_LINE_SIZE]; while (fgets(line, MAX_LINE_SIZE, fp) != NULL) { trim(line); if (strlen(line) == 0) { continue; } if (line[0] == '[' && line[strlen(line) - 1] == ']') { // 这是一个节(Section)的名称,忽略掉 continue; } char *p = strchr(line, '='); if (p == NULL) { // 没有找到等号,忽略掉 continue; } *p++ = '\0'; trim(line); trim(p); strncpy(kv[count].key, line, MAX_LINE_SIZE - 1); strncpy(kv[count].value, p, MAX_LINE_SIZE - 1); ++count; if (count >= max_count) { // 配对的键值对数量已经达到了最大值,停止读取 break; } } fclose(fp); return count; } // 定义一个函数,用于写入ini文件中的键值对 int write_ini_file(const char *filename, KeyValue *kv, int count) { FILE *fp = fopen(filename, "w"); if (fp == NULL) { return -1; } for (int i = 0; i < count; ++i) { fprintf(fp, "%s=%s\n", kv[i].key, kv[i].value); } fclose(fp); return 0; } int main() { // 读取ini文件中的键值对,并打印出来 KeyValue kv[1024]; int count = read_ini_file("config.ini", kv, 1024); for (int i = 0; i < count; ++i) { printf("%s=%s\n", kv[i].key, kv[i].value); } // 修改键值对 for (int i = 0; i < count; ++i) { if (strcmp(kv[i].key, "name") == 0) { strcpy(kv[i].value, "Alice"); break; } } // 写入ini文件 write_ini_file("config.ini", kv, count); return 0; } ``` 以上代码仅供参考,具体实现方式可以根据实际需求进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值