文件操作案例-配置文件读写

配置文件读写案例实现分析
1、 功能划分
a) 界面测试(功能集成)
自己动手规划接口模型。
b) 配置文件读写
i. 配置文件读(根据key,读取valude)
ii. 配置文件写(输入key、valude)
iii. 配置文件修改(输入key、valude)
iv. 优化 ===》接口要求紧 模块要求松
2、 实现及代码讲解
3、 测试。

#include"cfg_op.h"
#define MAXLEN 1024
int GetCfgItem(char *pFilename, char* pKey, char *pValue, int *pValueLen)
{
FILE *fp = NULL;
int ret = 0;
char buf[MAXLEN] = { 0 };
char *pTmp = NULL;

fp = fopen(pFilename, "r");


if (fp == NULL)
{
    ret = -1;
    printf("打开文件失败。\n");
    return ret;
}
while (!feof(fp))
{
    memset(buf,0,sizeof(buf));
    fgets(buf, MAXLEN, fp);//注意取出来的数据最后有一个/n结束符
    //printf("%s\n",buf);

    pTmp = strchr(buf,'=');
    if (pTmp == NULL)//没有找到'='
        continue;

    pTmp = strstr(buf, pKey);
    if (pTmp == NULL)//如判断pkey是不是在所在行
        continue;
    pTmp += strlen(pKey);// mykey1   = myvalue11111   =>    "   = myvalue11111   "

    pTmp = strchr(pTmp,'=');
    if (pTmp == NULL)
        continue;
    pTmp = pTmp + 1;  //=>" myvalue11111   "

    //pTmp = "    myvalue31111    ";
    trimSpace(pTmp, pValue);
    *pValueLen = strlen(pValue);
}

fclose(fp);
return 0;
}

int trimSpace(char *inbuf, char *outbuf)
{
int ret = 0;
char * p = inbuf;
int len = strlen(inbuf)-2;//减2的原因是最后有个'/n'结束符
int left = 0, right = len;
char *tmp = NULL;

if (!inbuf)
{
    ret = -1;
    printf("inbuf is NULL. \n");
    return -1;
}

while (p[right] == ' ')
    right--;

while (p[left] == ' ')
    left++;

if (left >= right)
{
    outbuf = NULL;
    return ret;
}
memset(outbuf, 0, strlen(outbuf));
strncpy(outbuf, p + left, right - left+1);
return ret;
}

//写配置项
//循环读每一行,检查key是否存在,若存在修改对应的value,若不存在在文件尾添加“key=value
/*本实现方法是将文件内容一行一行取出存入临时数组,修改目标行也存入临时数组,再将后面的再润如临时数组,
之后再重新创建同名文件,将数组内容写入文件*/
/该方法的实现有个缺陷就是如果文件比较大,临时数组就要申请较大内存/

/*新方法:将数据从文件filea取出存入新的文件fileb,然后将filea删除(remove),再将fileb改名成filea(rename),
这种方法的实现避免的较大文件需要申请较大内存的问题,但因为是和硬盘交互,速度上较慢*/

int WriteCfgItem(char *pFilename, char* pkey, char *pvalue, int ValueLen)
{

int rv = 0;
FILE *fp;
long len = 0;
char linebuf[100] = {0};
char filebuf[8 * 1024] = { 0 };
char *ptmp;
int itag = 0;

if (pFilename == NULL || pkey == NULL || pvalue == NULL)
{
    rv = -1;
    printf("parameter error.\n");
    goto EXIT;
}

fp = fopen(pFilename,"r+");
if (fp == NULL)
{
    fp == fopen(pFilename,"w+t");
    if (fp == NULL)
    {
        rv = -2;
        printf("fopen error.\n");
        goto EXIT;
    }
}

fseek(fp, 0L, SEEK_END);//把文件指针从0开始,移到文件末尾。
len = ftell(fp);//获取文件长度

if (len > 1024 * 8)
{
    rv = -3;
    printf("超过8k,不支持。\n");
    goto EXIT;
}

while (!feof(fp))
{
    //读每一行
    memset(linebuf, 0, sizeof(linebuf));
    ptmp = fgets(linebuf, 1024, fp);
    if (ptmp == NULL)
        break;

    ptmp = strstr(linebuf, pkey);
    if (ptmp == NULL)//关键字不在本行
    {
        strcat(filebuf, linebuf);
        continue;
    }
    else//关键字在本行
    {
        sprintf(linebuf, "%s=%s\n", pkey, pvalue);
        strcat(filebuf, linebuf);
        itag = 1;
    }
}

    if (itag == 0)//若关键字不存在,追加
    {
        fprintf(fp, "%s = %s\n", pkey, pvalue);
    }
    else//若关键字存在,则重新写文件内容
    {
        if (fp != NULL)
        {
            fclose(fp);
            fp = NULL;
        }
        fp = fopen(pFilename, "w+t");
        if (fp == NULL)
        {
            rv = -4;
            printf("fopen error.\n");
            goto EXIT;
        }
        fputs(filebuf, fp);
    }

EXIT:

if (fp != NULL)
    fclose(fp);

return rv;
}

=========测试框架===========

#include<stdlib.h>
#include"cfg_op.h"
#define  CFIGNAME "C:/mycfg.ini"
void mymenu()
{
printf("===========================\n");
printf("1 测试写配置文件。\n");
printf("2 测试读配置文件。\n");
printf("0 退出。\n");
printf("===========================\n");
}

int TWriteCfg()
{
char pItemName[100] = {0};
char pItemValue[100] = {0};
int itemValueLen = 0;
int ret = 0;

printf("\n请输入key:");
scanf("%s", &pItemName);
printf("\n请输入Value:");
scanf("%s", &pItemValue);

itemValueLen = strlen(pItemValue);
ret = WriteCfgItem(CFIGNAME, pItemName, pItemValue, itemValueLen);
if (ret != 0)
{
    printf("WriteCfgItem error \n");
    return ret;
}
printf("输入:%s = %s", pItemName, pItemValue);
return 0;
}

int TGetCfg()
{
char pKey[20] = {0};
char pValue[100] = { 0 };
int pValueLen = 0;
int ret = 0;

printf("\n请输入key:");
scanf("%s", &pKey);

pValueLen = strlen(pValue);
ret = GetCfgItem(CFIGNAME,pKey, pValue, &pValueLen);

if (ret != 0)
{
    printf("GetCfgItem error \n");
    return ret;
}
printf("pValue=%s\n", pValue);
printf("pValueLen=%d\n", pValueLen);
return 0;
}


int main()
{

int choice;
for (;;)
{
    mymenu();

    scanf("%d", &choice);

    switch (choice)
    {   
    case 1://写配置项
        TWriteCfg();
        break;
    case 2://读
        TGetCfg();
        break;
    case 0:
        exit(1);
    default:
        break;
    }
}
return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40878579/article/details/80143793