读取配置文件的C语言接口实现

在一些场合,需要对一些配置文件进行读取,去设置软件的参数,自己实现了一些接口函数,以供以后使用。

ConfigFile.c

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <ctype.h>
  4 #include <direct.h>
  5 #define MAX_LINE_LENGTH    256
  6 
  7 int read_line(FILE *fp, char *bp)
  8 {
  9     char c = '\0';
 10     int i = 0;
 11     bool isAssgin = 0;
 12     /* Read one line from the source file */
 13     while (1)
 14     {
 15         c = getc(fp);
 16         if (c == '\n')
 17         {
 18             break;
 19         }
 20 
 21         if (c == '\r')
 22         {
 23             continue;
 24         }
 25 
 26         if (c == '=')
 27         {
 28             isAssgin = 1;
 29         }
 30 
 31         if (feof(fp))
 32         {
 33             /* return FALSE on unexpected EOF */
 34             if (isAssgin == 1)
 35             {
 36                 bp[i] = '\0';
 37                 return(1);
 38             }
 39             else
 40             {
 41                 return(0);
 42             }
 43         }
 44         bp[i++] = c;
 45     }
 46     bp[i] = '\0';
 47     return(1);
 48 }
 49 /************************************************************************
 50 * Function:     Get_private_profile_int()
 51 * Arguments:    <char *> section - the name of the section to search for
 52 *               <char *> entry - the name of the entry to find the value of
 53 *               <int> def - the default value in the event of a failed read
 54 *               <char *> file_name - the name of the .ini file to read from
 55 * Returns:      the value located at entry
 56 *************************************************************************/
 57 int Get_private_profile_int(const char *section, const char *entry, int def, char *file_name)
 58 {
 59     FILE *fp = fopen(file_name, "r");
 60     //Try to fix the issue that the MAX_PATH should be 256, not 80
 61     char buff[MAX_LINE_LENGTH];
 62     char *ep;
 63     char t_section[MAX_LINE_LENGTH];
 64     char value[12];
 65     int len = strlen(entry);
 66     int i;
 67     //To support negative number convert
 68     bool b_IsNegative = false;
 69     if (!fp)
 70     {
 71         return(0);
 72     }
 73     sprintf(t_section, "[%s]", section); /* Format the section name */
 74     /*  Move through file 1 line at a time until a section is matched or EOF */
 75     do
 76     {
 77         if (!read_line(fp, buff))
 78         {
 79             fclose(fp);
 80             return(def);
 81         }
 82     }while (strcmp(buff, t_section));
 83     /* Now that the section has been found, find the entry.
 84      * Stop searching upon leaving the section's area. */
 85     do
 86     {
 87         if (!read_line(fp, buff) || buff[0] == '[') //130516 Willy modify '\0' to '[' for parser ini bug.
 88         {
 89             fclose(fp);
 90             return(def);
 91         }
 92     }while (strncmp(buff, entry, len));
 93     
 94     ep = strrchr(buff, '=');   /* Parse out the equal sign */
 95     ep++;
 96     if (!strlen(ep))           /* No setting? */
 97     {
 98         return(def);
 99     }
100     /* Copy only numbers fail on characters */
101     //To support negative number convert
102     if (ep[0] == '-')
103     {
104         b_IsNegative = true;
105         for (i = 1; isdigit(ep[i]); i++)
106         {
107             value[i - 1] = ep[i];
108         }
109         value[--i] = '\0';
110     }
111     else
112     {
113         for (i = 0; isdigit(ep[i]); i++)
114         {
115             value[i] = ep[i];
116         }
117         value[i] = '\0';
118     }
119     fclose(fp);                /* Clean up and return the value */
120     //To support negative number convert
121     if (b_IsNegative)
122     {
123         return (0 - atoi(value));
124     }
125     else  
126     {
127         return(atoi(value));
128     }
129 }
130 
131 
132 unsigned long long Get_private_profile_longlong(const char *section, const char *entry, unsigned long long def, char *file_name)
133 {
134     FILE *fp = fopen(file_name, "r");
135     char buff[MAX_LINE_LENGTH];
136     char *ep;
137     char t_section[MAX_LINE_LENGTH];
138     char value[16];
139     int len = strlen(entry);
140     int i;
141     if (!fp)
142     {
143         return(0);
144     }
145     sprintf(t_section, "[%s]", section); /* Format the section name */
146     /*  Move through file 1 line at a time until a section is matched or EOF */
147     do
148     {
149         if (!read_line(fp, buff))
150         {
151             fclose(fp);
152             return(def);
153         }
154     }while (strcmp(buff, t_section));
155     /* Now that the section has been found, find the entry.
156      * Stop searching upon leaving the section's area. */
157     do
158     {
159         if (!read_line(fp, buff) || buff[0] == '[') //130516 Willy modify '\0' to '[' for parser ini bug.
160         {
161             fclose(fp);
162             return(def);
163         }
164     }while (strncmp(buff, entry, len));
165     
166     ep = strrchr(buff, '=');   /* Parse out the equal sign */
167     ep++;
168     if (!strlen(ep))           /* No setting? */
169     {
170         return(def);
171     }
172     /* Copy only numbers fail on characters */
173     for (i = 0; isdigit(ep[i]); i++)
174     {
175         value[i] = ep[i];
176     }
177     value[i] = '\0';
178     fclose(fp);                /* Clean up and return the value */
179     return(_atoi64(value));
180 }
181 
182 /**************************************************************************
183 * Function:     Get_private_profile_string()
184 * Arguments:    <char *> section - the name of the section to search for
185 *               <char *> entry - the name of the entry to find the value of
186 *               <char *> def - default string in the event of a failed read
187 *               <char *> buffer - a pointer to the buffer to copy into
188 *               <int> buffer_len - the max number of characters to copy
189 *               <char *> file_name - the name of the .ini file to read from
190 * Returns:      the number of characters copied into the supplied buffer
191 ***************************************************************************/
192 int Get_private_profile_string(const char *section, const char *entry, const char *def, char *buffer, int buffer_len, char *file_name)
193 {
194 
195     FILE *fp = fopen(file_name, "r");
196     char buff[MAX_LINE_LENGTH];
197     char *ep;
198     char t_section[MAX_LINE_LENGTH];
199     int len = strlen(entry);
200     if (!fp)
201     {
202         return(0);
203     }
204     sprintf(t_section, "[%s]", section);  /* Format the section name */
205     /*  Move through file 1 line at a time until a section is matched or EOF */
206     do
207     {
208         if (!read_line(fp, buff))
209         {
210             strncpy(buffer, def, buffer_len);
211             return(strlen(buffer));
212         }
213     }while (strcmp(buff, t_section));
214     /* Now that the section has been found, find the entry.
215      * Stop searching upon leaving the section's area. */
216     do
217     {
218         if (!read_line(fp, buff) || buff[0] == '[') //130516 Willy modify '\0' to '[' for parser ini bug.
219         {
220             fclose(fp);
221             strncpy(buffer, def, buffer_len);
222             return(strlen(buffer));
223         }
224     }while (strncmp(buff, entry, len));
225 
226     ep = strrchr(buff, '=');   /* Parse out the equal sign */
227     do
228     {
229         ep++;
230     }while(!strncmp(ep, " ", 1));   //Remove the blank space
231 
232     /* Copy up to buffer_len chars to buffer */
233     strncpy(buffer, ep, buffer_len - 1);
234     buffer[buffer_len - 1] = '\0';
235     fclose(fp);               /* Clean up and return the amount copied */
236     return(strlen(buffer));
237 }
238 int Get_private_profile_hex(const char *section, const char *entry, int def, char *file_name)
239 {
240     char valBuf[16], valBuf2[16];
241     int data;
242 
243     memset(valBuf, 0, sizeof(valBuf));
244     memset(valBuf2, 0, sizeof(valBuf2));
245 
246     sprintf(valBuf2, "0x%x", def);
247     Get_private_profile_string(section, entry, valBuf2, &valBuf[0], sizeof(valBuf), file_name);
248     data = 0;
249     sscanf(valBuf, "0x%x", &data);
250     return data;
251 }
252 
253 /*************************************************************************
254  * Function:    Write_private_profile_string()
255  * Arguments:   <char *> section - the name of the section to search for
256  *              <char *> entry - the name of the entry to find the value of
257  *              <char *> buffer - pointer to the buffer that holds the string
258  *              <char *> file_name - the name of the .ini file to read from
259  * Returns:     TRUE if successful, otherwise FALSE
260  *************************************************************************/
261 int Write_private_profile_string(const char *section, const char *entry, char *buffer, char *file_name)
262 {
263     FILE *rfp, *wfp;
264     char tmp_name[15];
265     //Try to fix the issue that the MAX_PATH should be 256, not 80
266     char buff[MAX_LINE_LENGTH];
267     char t_section[MAX_LINE_LENGTH];
268     int len = strlen(entry);
269     tmpnam(tmp_name); /* Get a temporary file name to copy to */
270     sprintf(t_section, "[%s]", section); /* Format the section name */
271 
272     rfp = fopen(file_name, "r");
273     if (!rfp)  /* If the .ini file doesn't exist */
274     {
275         wfp = fopen(file_name, "w");
276         if (!wfp) /*  then make one */
277         {
278             return(0);
279         }
280         fprintf(wfp, "%s\n", t_section);
281         fprintf(wfp, "%s=%s\n", entry, buffer);
282         fclose(wfp);
283         return(1);
284     }
285 
286     wfp = fopen(tmp_name, "w");
287     if (!wfp)
288     {
289         fclose(rfp);
290         return(0);
291     }
292 
293     /* Move through the file one line at a time until a section is
294      * matched or until EOF. Copy to temp file as it is read. */
295     do
296     {
297         if (!read_line(rfp, buff))
298         {
299             /* Failed to find section, so add one to the end */
300             fprintf(wfp, "\n%s\n", t_section);
301             fprintf(wfp, "%s=%s\n", entry, buffer);
302             /* Clean up and rename */
303             fclose(rfp);
304             fclose(wfp);
305             unlink(file_name);
306             rename(tmp_name, file_name);
307             return(1);
308         }
309         fprintf(wfp, "%s\n", buff);
310     }while (strcmp(buff, t_section));
311 
312     /* Now that the section has been found, find the entry. Stop searching
313      * upon leaving the section's area. Copy the file as it is read
314      * and create an entry if one is not found.  */
315     while (1)
316     {
317         if (!read_line(rfp, buff))
318         {
319             /* EOF without an entry so make one */
320             fprintf(wfp, "%s=%s\n", entry, buffer);
321             /* Clean up and rename */
322             fclose(rfp);
323             fclose(wfp);
324             unlink(file_name);
325             rename(tmp_name, file_name);
326             return(1);
327 
328         }
329         if (!strncmp(buff, entry, len) || buff[0] == '\0')
330         {
331             break;
332         }
333         fprintf(wfp, "%s\n", buff);
334     }
335 
336     if (buff[0] == '\0')
337     {
338         fprintf(wfp, "%s=%s\n", entry, buffer);
339         do
340         {
341             fprintf(wfp, "%s\n", buff);
342         }
343         while (read_line(rfp, buff));
344     }
345     else
346     {
347         fprintf(wfp, "%s=%s\n", entry, buffer);
348         while (read_line(rfp, buff))
349         {
350             fprintf(wfp, "%s\n", buff);
351         }
352     }
353     /* Clean up and rename */
354     fclose(wfp);
355     fclose(rfp);
356     unlink(file_name);
357     rename(tmp_name, file_name);
358     return(1);
359 }
360 
361 int Write_private_profile_int(const char *section, const char *entry, int data, char *file_name)
362 {
363     char valBuf[16];
364     memset(valBuf, 0, 16);
365     sprintf(valBuf, "%d", data);
366     return Write_private_profile_string(section, entry, valBuf, file_name);
367 }
368 
369 unsigned long long Write_private_profile_longlong(const char *section, const char *entry, unsigned long long data, char *file_name)
370 {
371     char valBuf[16];
372     memset(valBuf, 0, 16);
373     sprintf(valBuf, "%Lu", data);
374     return Write_private_profile_string(section, entry, valBuf, file_name);
375 }

ConfigFile.h

 1 #ifndef _CONFIGFILE_H_
 2 #define _CONFIGFILE_H_
 3 
 4 extern int Get_private_profile_int(const char *section, const char *entry, int def, char *file_name);
 5 extern unsigned long long Get_private_profile_longlong(const char *section, const char *entry, unsigned long long def, char *file_name);
 6 extern int Get_private_profile_string(const char *section, const char *entry, const char *def, char *buffer, int buffer_len, char *file_name);
 7 extern int Get_private_profile_hex(const char *section, const char *entry, int def, char *file_name);
 8 
 9 extern int Write_private_profile_string(const char *section, const char *entry, char *buffer, char *file_name);
10 extern int Write_private_profile_int(const char *section, const char *entry, int data, char *file_name);
11 extern unsigned long long Write_private_profile_longlong(const char *section, const char *entry, unsigned long long data, char *file_name);
12 
13 #endif //_CONFIGFILE_H_

测试:

当前目录下MKRDTOOL.ini文件的内容为

测试源码:main.c

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <ctype.h>
 4 #include <direct.h>
 5 #include "GetConfig.h"
 6 #define DEFAULT_INI_FILE "\\MKRDTOOL.ini"
 7 
 8 int main(int argc, char* argv[])
 9 {
10     char ProductModel[80];
11     char iniFile[256];
12     char *buffer;
13     buffer = getcwd(NULL, 0);
14     strcpy(iniFile, buffer);
15     strcat(iniFile,DEFAULT_INI_FILE);
16 
17     Get_private_profile_string("Setting", "ProductModel", "SS", ProductModel, sizeof(ProductModel), iniFile);
18     printf("ProductModel:%s\n",ProductModel);
19 
20     unsigned char enExtendBlock = Get_private_profile_int("FwSetting", "EnExtendBlock", 1, iniFile);
21     printf("enExtendBlock:%d\n",enExtendBlock);
22 
23     int MPVersion = 100;
24     Write_private_profile_int("Setting", "MPVersion", MPVersion, iniFile);
25 
26     sprintf(ProductModel,"ABCSFE!!221");
27     Write_private_profile_string("Setting", "ProductModel", ProductModel, iniFile);
28 
29 }

猜你喜欢

转载自www.cnblogs.com/hwli/p/9253677.html