一共四个文件:inifile.c,inifile.h,main.c.程序中用到的配置文件myconfig.ini不需要提前存在,代码中有创建的过程。
inifile.h是inifile.c的头文件完成读写配置文件的功能,main.c调用inifile完成的功能。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
// inifile.h /** * @file * @brief initialization file read and write API * -size of the ini file must less than 16K * -after '=' in key value pair, can not support empty char. this would not like WIN32 API * -support comment using ';' prefix * -can not support multi line * @author Deng Yangjun * @date 2007-1-9 * @version 0.2 */ #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_ |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 |
inifile.c /** * @file * @brief initialization file read and write API implementation * @author Deng Yangjun * @date 2007-1-9 * @version 0.2 */ #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, you can redefine MAX_FILE_SIZE to fit the big file buf[i]=fgetc(in); } buf[i]='\0'; *file_size = i; fclose(in); return 1; } static int newline(char c) { return ('\n' == c || '\r' == c )? 1 : 0; } static int end_of_string(char c) { return '\0'==c? 1 : 0; } static int left_barce(char c) { return LEFT_BRACE == c? 1 : 0; } static int isright_brace(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( !end_of_string(p[i]) ) { //find the section if( ( 0==i || newline(p[i-1]) ) && left_barce(p[i]) ) { int section_start=i+1; //find the ']' do { i++; } while( !isright_brace(p[i]) && !end_of_string(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( ! (newline(p[i-1]) && left_barce(p[i])) && !end_of_string(p[i]) ) { int j=0; //get a new line newline_start = i; while( !newline(p[i]) && !end_of_string(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; } /** read string in initialization file\n * retrieves a string from the specified section in an initialization file section [in] name of the section containing the key name key [in] name of the key pairs to value value [in] pointer to the buffer that receives the retrieved string size [in] size of result's buffer default_value [in] default value of result file [in] path of the initialization file 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; } } /** read int value in initialization file\n * retrieves int value from the specified section in an initialization file section [in] name of the section containing the key name key [in] name of the key pairs to value default_value [in] default value of result file [in] path of the initialization file 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 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
// main.c #include <stdio.h> #include "inifile.h" #define BUF_SIZE 256 int main() { const char *file ="myconfig.ini";//这里也可以改成“myconfig,txt” const char *section = "student"; const char *name_key = "name"; const char *age_key = "age"; char name[BUF_SIZE]={0}; int age; //write name key value pair if(!write_profile_string(section,name_key,"Tony",file)) { printf("write name pair to ini file fail\n"); return -1; } //write age key value pair if(!write_profile_string(section,age_key,"20",file)) { printf("write age pair to ini file fail\n"); return -1; } printf("[%s]\n",section); //read string pair, test read string value if(!read_profile_string(section, name_key, name, BUF_SIZE,"",file)) { printf("read ini file fail\n"); return -1; } else { printf("%s=%s\n",name_key,name); } //read age pair, test read int value. //if read fail, return default value age = read_profile_int(section,age_key,0,file); printf("%s=%d\n",age_key,age); return 0; } |
发表评论
要发表评论,您必须先登录。