C语言实现配置文件的查找key的value,根据key修改value.
实现环境:windows 7 vs2010
配置文件cfg.ini:
oracle=orcl
sql=mysql
程序实现根据key :oracle 来获取value :orcl
程序实现根据key :oracle 来修改value :orcl 为abc
cf_op.h 头文件
#define LineMaxLen 2048
#define KeyMaxLen 128
#define MaxFileLength 1024*10
#ifndef CF_OP_H
#define CF_OP_H
#ifdef __cplusplus
extern "C" {
#endif
int GetCfItem(const char *pFileName /*in*/, char *pKey /*in*/, char * pValue/*in out*/, int * pValueLen /*out*/);
int SetCfItem(const char *pFileName /*in*/, char *pKey /*in*/, char *pValue/*in*/);
#ifdef __cplusplus
}
#endif
#endif
cf_op.c 文件
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"cf_op.h"
/* 该函数作用是判断linebuf中是否存在 pKey 这里使用的完全匹配
stu=123
student=124
这里都有stu,substr函数功能就是排除这种情况的
*/
static char *substr(char *linebuf,char *pKey)
{
char *pTmp = NULL, *pRv = NULL;
int lenKey = 0,len = 0;
if (linebuf==NULL || pKey==NULL)
{
printf("func parameter err: (str==NULL || substr==NULL)");
return pRv;
}
pRv = strstr(linebuf, pKey);
if(pRv == NULL)
{
return pRv;
}
pTmp = pRv;
lenKey = strlen(pKey);
while(*pTmp != '\0' && *pTmp != ' '&& *pTmp != '=' && *pTmp != '\n')
{
len++;
pTmp++;
if(len>lenKey)
{
break;
}
}
if (lenKey != len)
{
return NULL;
}
return pRv;
}
//实现流程
//打开文件
//按照行的方式 循环读文件
//解析每一行,若匹配key关键字,在进行value值的提取
//提取value值需要 去除前后空格
int GetCfItem(const char *pFileName, char *pKey, char * pValue, int * pValueLen )
{
int rv = 0;
FILE *fp = NULL;
char linebuf[LineMaxLen];
char *pTmp = NULL, *pBegin = NULL, *pEnd = NULL;
if (pFileName==NULL||pKey==NULL||pValue==NULL||pValueLen==NULL)
{
rv = -1;
printf("func GetCfItem paramter err!");
goto End;
}
fp = fopen(pFileName,"r");//以只读方式打开文件
if (fp==NULL)
{
rv = -2;
printf("fopen file err %d (fp==NULL)",rv);
goto End;
}
while(!feof(fp))
{
memset(linebuf,0,LineMaxLen);
pTmp = fgets(linebuf, LineMaxLen, fp);// 按行读取
if (pTmp==NULL)
{
break;
}
pTmp = substr(linebuf, pKey);//判断key是否在该行
if (pTmp==NULL)
{
continue;
}
pTmp = strchr(linebuf, '=');// 判断该行可有'='
if (pTmp==NULL)
{
continue;
}
pTmp=pTmp+1;// 从等号后面开始
while (1)//获取value 起点
{
if(*pTmp==' ')
{
pTmp++;
}
else
{
pBegin = pTmp;
if(*pBegin == '\n'||*pBegin=='\0')
{
rv = -3;
printf("The key %s don't have value",pKey);
}
break;
}
}
while (1)//获取valude结束点
{
if(*pTmp==' '||*pTmp=='\n'||*pTmp=='\0')
{
break;
}
else
{
pTmp++;
}
}
pEnd = pTmp;
*pValueLen = pEnd-pBegin;
memcpy(pValue,pBegin,*pValueLen);//拷贝
*(pValue+*pValueLen)='\0';
break;
}
if(pBegin==NULL) // 没有找到key
{
printf("can't find the key:%s \n",pKey);
rv = -4;
}
End:
if (fp!=NULL)
{
fclose(fp);
}
return rv;
}
//实现流程
//循环读每一行,检查key配置项是否存在 若存在修改对应value值
//若不存在,在文件末尾 添加 "key = value"
//难点:如何修改文件流中的值
int SetCfItem(const char *pFileName, char *pKey, char *pValue)
{
int rv = 0;
int length = 0,iFlag = 0;
FILE *fp = NULL;
char filebuf[MaxFileLength];
char linebuf[LineMaxLen];
char *pTmp = NULL;
memset(filebuf, 0, MaxFileLength);
if (pFileName==NULL||pKey==NULL||pValue==NULL)
{
rv = -1;
printf("func WriteCfItem paramter err!");
goto End;
}
fp = fopen(pFileName,"r+");
if (fp==NULL)
{
rv = -2;
printf("fopen file err:%d",rv);
goto End;
}
fseek(fp, 0L, SEEK_END);
//获取文件长度;
length = ftell(fp);
fseek(fp, 0L, SEEK_SET);
if (length>MaxFileLength)
{
rv = -3;
printf("file too long unspport:%d",rv);
goto End;
}
while (!feof(fp))
{
//读每一行
memset(linebuf, 0, sizeof(linebuf));
pTmp = fgets(linebuf, LineMaxLen, fp);
if(pTmp==NULL)
{
break;
}
pTmp = substr(linebuf, pKey);
if(pTmp==NULL)
{
strcat(filebuf, linebuf);
continue;
}
else
{
sprintf(linebuf,"%s=%s\n", pKey, pValue);
strcat(filebuf, linebuf);
iFlag = 1;//若存在key
}
}
//若不存在 追加
if (iFlag == 0)
{
fprintf(fp,"\n%s=%s", pKey, pValue);
}
else//若存在
{
if (fp!=NULL)
{
fclose(fp);
}
fp = fopen(pFileName,"w+");
if (fp==NULL)
{
rv = -4;
printf("fopen file err:%d",rv);
goto End;
}
fputs(filebuf, fp);//写回文件
}
End:
if (fp!=NULL)
{
fclose(fp);
}
return rv;
}
测试主函数test_main.c:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include"cf_op.h"
void Test_SetCfItem()
{
int rv = 0;
char *pFileName="cfg.ini";
char key[KeyMaxLen];
char value[KeyMaxLen];
memset(key, 0, sizeof(key));
memset(value, 0, sizeof(value));
printf("\n please input the key:",key);
scanf("%s",key);
printf("\n please input the value:",value);
scanf("%s",value);
rv = SetCfItem(pFileName,key,value);
if (rv!=0)
{
printf("set the key value err! \n");
return;
}
printf("set the key value success! \n");
}
void Test_GetCfItem()
{
char *pFileName="cfg.ini";
char key[KeyMaxLen];
char value[KeyMaxLen];
int len = 0, rv = 0;
memset(key, 0, sizeof(key));
memset(value, 0, sizeof(value));
printf("\n please input the key:",key);
scanf("%s",key);
rv = GetCfItem(pFileName,key,value,&len);
if(rv!=0)
{
printf("Get the key value err!");
return;
}
printf("\n %s=%s",key,value);
}
void main_menu()
{
printf("\n1 Test GetCfItem(测试读取配置文件) ");
printf("\n2 Test SetCfItem(测试设置配置文件) ");
printf("\n0 exit(0) (程序退出) ");
printf("\nplease enter your choice:[1/2/0]: ");
}
void main()
{
int choice;
while (1)
{
main_menu();
scanf("%d",&choice);
switch(choice)
{
case 0:
exit(0);
case 1:
Test_GetCfItem(); break;
case 2:
Test_SetCfItem(); break;
default:
exit(0);
}
}
system("pause");
}
测试结果: