/*
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 [email protected]
*@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 [email protected]
*@version 0.1
*@create 2007-1-14
*@modify 2007-1-14
*@brief implement ini file operation
*@note
*@history
*/
#include
#include
#include
#include
#include
#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 ;
}
/*
*
*
*
*
*/
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
* @param section
* @param key
* @param value
* @return
*/
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