1、inifile.c 的内容:
- /**
- * @file
- * @brief initialization file read and write API implementation
- * @author Deng Yangjun
- * @date 2007-1-9
- * @version 0.1
- */
- #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 1024*16
- #define LEFT_BRACE '['
- #define RIGHT_BRACE ']'
- static int load_ini_file(const char *file, char *buf,int *file_size)
- {
- FILE *in = NULL;
- int i=0;
- *file_size =0;
- assert(file !=NULL);
- assert(buf !=NULL);
- in = fopen(file,"r");
- if( NULL == in) {
- return 0;
- }
- buf[i]=fgetc(in);
-
- //load initialization file
- while( buf[i]!= (char)EOF) {
- i++;
- assert( i < MAX_FILE_SIZE); //file too big
- buf[i]=fgetc(in);
- }
-
- 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 string in initialization file\n
- * retrieves a string from the specified section in an initialization file
- *@param section [in] name of the section containing the key name
- *@param key [in] name of the key pairs to value
- *@param value [in] pointer to the buffer that receives the retrieved string
- *@param size [in] size of value buffer
- *@param default_value [in] defualt value of result
- *@param file [in] path of the initialization file
- *@return 1 : read success; \n 0 : read fail
- */
- int read_profile_string( const char *section, const char *key,char *value,
- int size, const char *default_value, 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))
- {
- if(default_value!=NULL)
- {
- strncpy(value,default_value, size);
- }
- return 0;
- }
- if(!parse_file(section,key,buf,&sec_s,&sec_e,&key_s,&key_e,&value_s,&value_e))
- {
- if(default_value!=NULL)
- {
- strncpy(value,default_value, size);
- }
- 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;
- }
- }
- /**
- *@brief int value in initialization file\n
- * retrieves int value from the specified section in an initialization file
- *@param section [in] name of the section containing the key name
- *@param key [in] name of the key pairs to value
- *@param default_value [in] defualt value of result
- *@param file [in] path of the initialization file
- *@return profile int value,if read fail, return default value
- */
- 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),NULL,file))
- {
- return default_value;
- }
- else
- {
- return atoi(value);
- }
- }
- /**
- * @brief write a profile string to a ini file
- * @param section [in] name of the section,can't be NULL and empty string
- * @param key [in] name of the key pairs to value, can't be NULL and empty string
- * @param value [in] profile string value
- * @param file [in] path of ini file
- * @return 1 : success\n 0 : failure
- */
- 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
2、inifile.h的内容:
- /**
- * @file
- * @brief initialization file read and write API
- * @author Deng Yangjun
- * @date 2007-1-9
- * @version 0.1
- */
- #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 *default_value, 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_
3、测试程序main.cpp
- #include <iostream>
- #include "inifile.h"
- using namespace std;
- int main(int argc, char **argv)
- {
- char section[256];
- char key[256];
- char file[256];
- char value[256];
- char *default_value = "mm";
- char *qstr = "quit";
- memset(section, 0, sizeof(value));
- memset(key, 0, sizeof(key));
- memset(file, 0, sizeof(file));
- memset(value, 0, sizeof(value));
- while(true)
- {
- cout << "Please input the follow section:\n";
- cout << "\t【section】 【key】 【file】"
- << endl;
- cin >> section;
- if((strncmp(qstr, section, sizeof(qstr)) == 0))
- {
- return 0;
- }
- cin >> key >> file;
- cout << "The section is " << section << endl;
- cout << "The key is " << key << endl;
- cout << "The file is " << file << endl;
- read_profile_string(section, key, value, sizeof(value), default_value, file);
- cout << "The value of【section】: " << section << "【key】: " << key << " is" << endl;
- cout << "\t" << value << endl;
- cout << endl;
- }
- return 0;
- }