前言:
发现公司的读取配置文件有bug,于是也出于练手的目的,自己写了一个。
源码如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <signal.h>
#include <assert.h>
#define MAX_BUFFER 1024
int ReadCfg(FILE *fp, char *section, char *key, char *value, int reflag)
{
char buf[MAX_BUFFER];
char sec_txt[MAX_BUFFER];
char *ptr;
int find, mval;
assert(fp != NULL && section != NULL && key != NULL);
find = 0;
sprintf(sec_txt, "[%s]", section);
if (reflag == 1)
{
rewind(fp);
while(fgets(buf, sizeof(buf), fp))
{
/* filter the blank before */
for (ptr=buf; *ptr==' '; ptr++);
/* skip the comment and empty line */
if (*ptr == 10 ||
*ptr == 13 ||
*ptr == '#' ||
*ptr == '//' ||
strstr(ptr, sec_txt) == NULL
)
continue;
/* section found */
find = 1;
break;
}
}
if(reflag == 1 && !find) return -1;
mval = 0;
while (fgets(buf, sizeof(buf), fp))
{
/* filter the blank before */
for (ptr=buf; *ptr==' '; ptr++);
/* find the key until reach the next section if not a multi-value */
if (*ptr == '[')
{
/* point to the end of the file for do not read anymore */
fseek(fp, 0, SEEK_END);
return mval == 0 ? -2 : 0;
}
/* skip empty line and comment and not include the key line */
if (*ptr == 10 ||
*ptr == 13 ||
*ptr == '#' ||
*ptr == '//' ||
(mval == 0 && (ptr = strstr(ptr,key)) == NULL)
)
continue;
/* if multi-value will do not need local the value */
if (mval == 0)
{
/* local the symbol '=' */
for(ptr+=strlen(key); *ptr == ' '; ptr++);
if (*ptr != '=') return -3;
/* local the value start */
for (; *(++ ptr) == ' '; );
if (*ptr == 13 || *ptr == 10 || *ptr == 0) return -3;
}
/* mark as value end when meet a comment or end of line */
for (find=0; *(ptr+find) && *(ptr+find) != '#' ; find++);
/* skip the blank or enter(Win:1310/Unix:10) after value */
for (; *(ptr+find-1) == ' ' ||
*(ptr+find-1) == 10 ||
*(ptr+find-1) == 13;
find --);
/* whether multi-value */
if (*(ptr+find-1) == '//')
{
mval ++;
if (*(ptr+find-2) == ' ')
*(ptr+find-1) = 0x0;
else
{
*(ptr+find-1) = 0x20;
*(ptr+find) = 0x0;
}
}
else *(ptr+find) = 0x0;
if (mval != 0)
{
strcat(value, ptr);
continue;
}
*(ptr+find) = 0x0;
strcpy(value, ptr);
return 0;
}
return mval == 0 ? -2 : 0;
}
int main(int argc, char **argv)
{
int i, rint;
int reflag = 1;
char buf[128];
FILE *fp;
fp = fopen("boss_sql.cfg","r");
i = 0;
/* while((rint = ReadCfg(fp, "bossfunc", "bosssql", buf, reflag --)) >= 0) */
while((rint = ReadCfg(fp, argv[1], argv[2], buf, reflag --)) >= 0)
{
printf("==============================/n");
printf("buf=%s, rint=%d/n", buf, rint);
printf("==============================/n");
}
printf("End !!!/n");
}
测试例子:
cat c.txt
[bossmsisdn]
bosssql = SELECT aa, bb, cc FROM dual
filename = boss_func.txt
bosssql = SELECT aa, bb, cc FROM dual
bosssql = SELECT aa, bb, cc FROM dual
[bossfunc]
filename = boss_func.txt
bosssql = SELECT aa, bb, cc / # liangdl
FROM dual / # liangdl
/
WHERE cc = aa # liangdl/
[bossmas]
filename = boss_mas.txt
bosssql = SELECT aa1111, bb/
/
FROM dual /
编译、运行及结果:
$ gcc -o readcfg readcfg.c
$ readcfg c.txt section name
file=c.txt,section=section,key=name
value=liangdl[7],0
将section 这个段中的key 为name 的值取出来了。
实现的方法感觉还是有点傻,不知道还有没有更好的算法来精简一下代码。
C 读取配置文件函数
最新推荐文章于 2021-05-17 12:36:58 发布