Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2161154
  • 博文数量: 361
  • 博客积分: 10828
  • 博客等级: 上将
  • 技术积分: 4161
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-20 14:34
文章分类

全部博文(361)

文章存档

2011年(132)

2010年(229)

分类: C/C++

2011-10-13 15:19:15

1、inifile.c 的内容:
 
  1. /**
  2.  * @file
  3.  * @brief initialization file read and write API implementation
  4.  * @author Deng Yangjun
  5.  * @date 2007-1-9
  6.  * @version 0.1
  7.  */
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <assert.h>
  11. #include <string.h>
  12. #include <ctype.h>

  13. #include "inifile.h"

  14. #ifdef __cplusplus
  15. extern "C"
  16. {
  17. #endif

  18. #define MAX_FILE_SIZE 1024*16
  19. #define LEFT_BRACE '['
  20. #define RIGHT_BRACE ']'

  21. static int load_ini_file(const char *file, char *buf,int *file_size)
  22. {
  23.     FILE *in = NULL;
  24.     int i=0;
  25.     *file_size =0;

  26.     assert(file !=NULL);
  27.     assert(buf !=NULL);

  28.     in = fopen(file,"r");
  29.     if( NULL == in) {
  30.         return 0;
  31.     }

  32.     buf[i]=fgetc(in);
  33.     
  34.     //load initialization file
  35.     while( buf[i]!= (char)EOF) {
  36.         i++;
  37.         assert( i < MAX_FILE_SIZE); //file too big
  38.         buf[i]=fgetc(in);
  39.     }
  40.     
  41.     buf[i]='\0';
  42.     *file_size = i;

  43.     fclose(in);
  44.     return 1;
  45. }

  46. static int isnewline(char c)
  47. {
  48.     return ('\n' == c || '\r' == c )? 1 : 0;
  49. }
  50. static int isend(char c)
  51. {
  52.     return '\0'==c? 1 : 0;
  53. }
  54. static int isleftbarce(char c)
  55. {
  56.     return LEFT_BRACE == c? 1 : 0;
  57. }
  58. static int isrightbrace(char c )
  59. {
  60.     return RIGHT_BRACE == c? 1 : 0;
  61. }
  62. static int parse_file(const char *section, const char *key, const char *buf,int *sec_s,int *sec_e,
  63.                      int *key_s,int *key_e, int *value_s, int *value_e)
  64. {
  65.     const char *p = buf;
  66.     int i=0;

  67.     assert(buf!=NULL);
  68.     assert(section != NULL && strlen(section));
  69.     assert(key != NULL && strlen(key));

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

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

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

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

  82.                 i++;

  83.                 //Skip over space char after ']'
  84.                 while(isspace(p[i])) {
  85.                     i++;
  86.                 }

  87.                 //find the section
  88.                 *sec_s = section_start;
  89.                 *sec_e = i;

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

  95.                     while( !isnewline(p[i]) && !isend(p[i]) ) {
  96.                         i++;
  97.                     }
  98.                     
  99.                     //now i is equal to end of the line
  100.                     j = newline_start;

  101.                     if(';' != p[j]) //skip over comment
  102.                     {
  103.                         while(j < i && p[j]!='=') {
  104.                             j++;
  105.                             if('=' == p[j]) {
  106.                                 if(strncmp(key,p+newline_start,j-newline_start)==0)
  107.                                 {
  108.                                     //find the key ok
  109.                                     *key_s = newline_start;
  110.                                     *key_e = j-1;

  111.                                     *value_s = j+1;
  112.                                     *value_e = i;

  113.                                     return 1;
  114.                                 }
  115.                             }
  116.                         }
  117.                     }

  118.                     i++;
  119.                 }
  120.             }
  121.         }
  122.         else
  123.         {
  124.             i++;
  125.         }
  126.     }
  127.     return 0;
  128. }

  129. /**
  130. *@brief read string in initialization file\n
  131. * retrieves a string from the specified section in an initialization file
  132. *@param section [in] name of the section containing the key name
  133. *@param key [in] name of the key pairs to value
  134. *@param value [in] pointer to the buffer that receives the retrieved string
  135. *@param size [in] size of value buffer
  136. *@param default_value [in] defualt value of result
  137. *@param file [in] path of the initialization file
  138. *@return 1 : read success; \n 0 : read fail
  139. */
  140. int read_profile_string( const char *section, const char *key,char *value,
  141.          int size, const char *default_value, const char *file)
  142. {
  143.     char buf[MAX_FILE_SIZE]={0};
  144.     int file_size;
  145.     int sec_s,sec_e,key_s,key_e, value_s, value_e;

  146.     //check parameters
  147.     assert(section != NULL && strlen(section));
  148.     assert(key != NULL && strlen(key));
  149.     assert(value != NULL);
  150.     assert(size > 0);
  151.     assert(file !=NULL &&strlen(key));

  152.     if(!load_ini_file(file,buf,&file_size))
  153.     {
  154.         if(default_value!=NULL)
  155.         {
  156.             strncpy(value,default_value, size);
  157.         }
  158.         return 0;
  159.     }

  160.     if(!parse_file(section,key,buf,&sec_s,&sec_e,&key_s,&key_e,&value_s,&value_e))
  161.     {
  162.         if(default_value!=NULL)
  163.         {
  164.             strncpy(value,default_value, size);
  165.         }
  166.         return 0; //not find the key
  167.     }
  168.     else
  169.     {
  170.         int cpcount = value_e -value_s;

  171.         if( size-1 < cpcount)
  172.         {
  173.             cpcount = size-1;
  174.         }
  175.     
  176.         memset(value, 0, size);
  177.         memcpy(value,buf+value_s, cpcount );
  178.         value[cpcount] = '\0';

  179.         return 1;
  180.     }
  181. }

  182. /**
  183. *@brief int value in initialization file\n
  184. * retrieves int value from the specified section in an initialization file
  185. *@param section [in] name of the section containing the key name
  186. *@param key [in] name of the key pairs to value
  187. *@param default_value [in] defualt value of result
  188. *@param file [in] path of the initialization file
  189. *@return profile int value,if read fail, return default value
  190. */
  191. int read_profile_int( const char *section, const char *key,int default_value,
  192.                 const char *file)
  193. {
  194.     char value[32] = {0};
  195.     if(!read_profile_string(section,key,value, sizeof(value),NULL,file))
  196.     {
  197.         return default_value;
  198.     }
  199.     else
  200.     {
  201.         return atoi(value);
  202.     }
  203. }

  204. /**
  205.  * @brief write a profile string to a ini file
  206.  * @param section [in] name of the section,can't be NULL and empty string
  207.  * @param key [in] name of the key pairs to value, can't be NULL and empty string
  208.  * @param value [in] profile string value
  209.  * @param file [in] path of ini file
  210.  * @return 1 : success\n 0 : failure
  211.  */
  212. int write_profile_string(const char *section, const char *key,
  213.                     const char *value, const char *file)
  214. {
  215.     char buf[MAX_FILE_SIZE]={0};
  216.     char w_buf[MAX_FILE_SIZE]={0};
  217.     int sec_s,sec_e,key_s,key_e, value_s, value_e;
  218.     int value_len = (int)strlen(value);
  219.     int file_size;
  220.     FILE *out;

  221.     //check parameters
  222.     assert(section != NULL && strlen(section));
  223.     assert(key != NULL && strlen(key));
  224.     assert(value != NULL);
  225.     assert(file !=NULL &&strlen(key));

  226.     if(!load_ini_file(file,buf,&file_size))
  227.     {
  228.         sec_s = -1;
  229.     }
  230.     else
  231.     {
  232.         parse_file(section,key,buf,&sec_s,&sec_e,&key_s,&key_e,&value_s,&value_e);
  233.     }

  234.     if( -1 == sec_s)
  235.     {
  236.         
  237.         if(0==file_size)
  238.         {
  239.             sprintf(w_buf+file_size,"[%s]\n%s=%s\n",section,key,value);
  240.         }
  241.         else
  242.         {
  243.             //not find the section, then add the new section at end of the file
  244.             memcpy(w_buf,buf,file_size);
  245.             sprintf(w_buf+file_size,"\n[%s]\n%s=%s\n",section,key,value);
  246.         }
  247.     }
  248.     else if(-1 == key_s)
  249.     {
  250.         //not find the key, then add the new key & value at end of the section
  251.         memcpy(w_buf,buf,sec_e);
  252.         sprintf(w_buf+sec_e,"%s=%s\n",key,value);
  253.         sprintf(w_buf+sec_e+strlen(key)+strlen(value)+2,buf+sec_e, file_size - sec_e);
  254.     }
  255.     else
  256.     {
  257.         //update value with new value
  258.         memcpy(w_buf,buf,value_s);
  259.         memcpy(w_buf+value_s,value, value_len);
  260.         memcpy(w_buf+value_s+value_len, buf+value_e, file_size - value_e);
  261.     }
  262.     
  263.     out = fopen(file,"w");
  264.     if(NULL == out)
  265.     {
  266.         return 0;
  267.     }
  268.     
  269.     if(-1 == fputs(w_buf,out) )
  270.     {
  271.         fclose(out);
  272.         return 0;
  273.     }

  274.     fclose(out);
  275.     return 1;
  276. }


  277. #ifdef __cplusplus
  278. }; //end of extern "C" {
  279. #endif
2、inifile.h的内容:
 
  1. /**
  2.  * @file
  3.  * @brief initialization file read and write API
  4.  * @author Deng Yangjun
  5.  * @date 2007-1-9
  6.  * @version 0.1
  7.  */

  8. #ifndef INI_FILE_H_
  9. #define INI_FILE_H_

  10. #ifdef __cplusplus
  11. extern "C"
  12. {
  13. #endif

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

  17. #ifdef __cplusplus
  18. }; //end of extern "C" {
  19. #endif

  20. #endif //end of INI_FILE_H_
 
3、测试程序main.cpp
  1. #include <iostream>

  2. #include "inifile.h"

  3. using namespace std;

  4. int main(int argc, char **argv)
  5. {
  6.     char section[256];
  7.     char key[256];
  8.     char file[256];
  9.     char value[256];
  10.     char *default_value = "mm";
  11.     char *qstr = "quit";

  12.     memset(section, 0, sizeof(value));
  13.     memset(key, 0, sizeof(key));
  14.     memset(file, 0, sizeof(file));
  15.     memset(value, 0, sizeof(value));

  16.     while(true)
  17.     {
  18.         cout << "Please input the follow section:\n";
  19.         cout << "\t【section】 【key】 【file】"
  20.             << endl;

  21.         cin >> section;
  22.         if((strncmp(qstr, section, sizeof(qstr)) == 0))
  23.         {
  24.             return 0;
  25.         }
  26.         cin    >> key >> file;

  27.         cout << "The section is " << section << endl;
  28.         cout << "The key is " << key << endl;
  29.         cout << "The file is " << file << endl;

  30.         read_profile_string(section, key, value, sizeof(value), default_value, file);
  31.         cout << "The value of【section】: " << section << "【key】: " << key << " is" << endl;
  32.         cout << "\t" << value << endl;
  33.         cout << endl;
  34.     }    
  35.     return 0;
  36. }
 
阅读(3187) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~