C语言 文件操作10--配置文件读写

 

//配置文件读写项目

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int writefile(const char *path/*in*/, char *pkey/*in*/, char *pvalue/*in*/){
    int ERRO_MSG = 0;
    if (path == NULL)
    {
        ERRO_MSG = 1;
        printf("path==NULL erro msg:%d\n", ERRO_MSG);
        return ERRO_MSG;
    }
    if (pkey == NULL)
    {
        ERRO_MSG = 2;
        printf("pkey==NULL erro msg:%d\n", ERRO_MSG);
        return ERRO_MSG;
    }
    if (pvalue == NULL)
    {
        ERRO_MSG = 3;
        printf("pvalue==NULL erro msg:%d\n", ERRO_MSG);
        return ERRO_MSG;
    }


    //定义文件读指针
    FILE *fpwr = fopen(path, "r+");
    //判断文件是否打开成功
    if (fpwr == NULL)
    {
        ERRO_MSG = 4;
        printf("文件打开失败!erro msg:%d;文件路径是%s\n", ERRO_MSG, path);
        return ERRO_MSG;
    }
    //判断原来配置文件里是否有该节点,有该配置节点执行修改操作,没有执行新增操作
    //准备字符指针数组,存储所有的键值对
    //定义下标
    int index = 0;
    char **bufarr = (char **)malloc(sizeof(char *)*(index + 1));
    //存储所有的配置文件(这里读取键值对,用fgets()函数比较合适,因为一行正好一个键值对)
    while (!feof(fpwr)){//feof()如果文件结束,则返回非0值,否则返回0
        //定义文件缓存数组
        char buf[100] = { 0 };
        //读取文件
        fgets(buf, 100, fpwr);
        //分配每个键值对内存存储空间
        char *ptemp = (char *)malloc(sizeof(char)*((int)strlen(buf) + 1));
        //拷贝字符串(buf定义在栈里,出了该函数会自动释放)
        strcpy(ptemp, buf);//strcpy()把从src地址开始且含有'\0'结束符的字符串复制到以dest开始的地址空间。
        //把字符串挂到指针数组上
        bufarr[index++] = ptemp;
        //为指针数组再次分配内存空间
        bufarr = (char **)realloc(bufarr, sizeof(char *)*(index + 1));
    }
    //为指针数组最后一个元素赋值NULL
    bufarr[index] = NULL;
    //开始查找对应键值对
    int a = 0;
    char *strindex = NULL;
    while (bufarr[a] != NULL){
        char *ptsource = bufarr[a];
        while (*ptsource != '\0'){
            int b = 0, flag = 0;
            //strchr函数原型:extern char *strchr(const char *s, char c); 返回首次出现c的位置的指针,返回的地址是被查找字符串指针开始的第一个与Val相同字符的指针,如果s中不存在c则返回NULL。
            char *ptempc = strchr(ptsource, pkey[b]);
            ptsource = strindex = ptempc;
            if (ptempc == NULL)
            {
                //没有找到该字符串
                flag = 1;
                break;
            }
            //开始匹配字符串
            while (pkey[b] != '\0'){
                //一个一个字符进行比较
                if (*(ptempc++) != pkey[b++])
                {
                    flag = 1;
                    strindex = NULL;
                    break;
                }
            }
            break;
        }
        if (strindex != NULL)
        {
            //执行修改操作
            //释放原来的字符串
            if (bufarr[a] != NULL)
            {
                free(bufarr[a]);
                char newbuf[100] = { 0 };
                sprintf(newbuf, "%s=%s\r\n", pkey, pvalue);
                //开辟新的字符串内存空间
                char *pnewstr = (char *)malloc(sizeof(char)*((int)strlen(newbuf) + 1));
                //复制字符串
                strcpy(pnewstr, newbuf);
                bufarr[a] = pnewstr;
            }
            break;
        }
        a++;
    }
    //没有找到对应的键
    if (strindex == NULL)
    {
        //执行新增操作
        bufarr = (char **)realloc(bufarr, sizeof(char *)*(index + 2));
        char newbuf[100] = { 0 };
        sprintf(newbuf, "%s=%s\r\n", pkey, pvalue);
        //开辟新的字符串内存空间
        char *pnewstr = (char *)malloc(sizeof(char)*((int)strlen(newbuf) + 1));
        //拷贝字符串
        strcpy(pnewstr, newbuf);
        bufarr[index] = pnewstr;
        bufarr[index + 1] = NULL;
    }
    int index2 = 0;
    //关闭文件指针
    if (fpwr != NULL)
    {
        fclose(fpwr);
    }
    //为什么这里我会重新打开文件呢
    //因为fopen()操作了文件指针fpwr,现在文件指针指向了文件末尾,(文件指针不同文件内部的位置指针,即fpwr(文件指针),(文件位置指针)fpwr->_ptr)
    //如果不关闭文件指针fpwr,那么写文件就会从文件末尾开始写,导致数据的追加
    //但是也有别的办法
    //就是使用rewind(fpwr)方法
    //函数名: rewind()
    //功 能 : 将文件内部的位置指针重新指向一个流(数据流 / 文件)的开头
    //注意:不是文件指针而是文件内部的位置指针,随着对文件的读写文件的位置指针(指向当前读写字节)向后移动。而文件指针是指向整个文件,如果不重新赋值文件指针不会改变。


    //打开新文件指针
    FILE *pfw = fopen(path, "w");
    //fflush(fpwr);
    //开始写文件
    while (bufarr[index2] != NULL){
        //将文件写入到缓存
        fputs(bufarr[index2], pfw);
        //释放字符指针数组元素内存
        free(bufarr[index2]);
        index2++;
    }
    //释放字符指针数组内存
    free(bufarr);
    //关闭文件指针
    if (pfw != NULL)
    {
        fclose(pfw);
    }
    return ERRO_MSG;
}

int readfile(const char *path/*in*/){
    int ERRO_MSG = 0;
    if (path == NULL)
    {
        ERRO_MSG = 1;
        printf("path!=NULL erro msg:%d\n", ERRO_MSG);
        return ERRO_MSG;
    }
    //定义文件指针
    FILE *fpr = NULL;
    //打开文件
    fpr = fopen(path, "r");
    if (fpr == NULL)
    {
        ERRO_MSG = 2;
        printf("文件打开失败 erro msg:%d\n", ERRO_MSG);
        return ERRO_MSG;
    }
    while (!feof(fpr)){
        char buf[100] = { 0 };
        fgets(buf, 100, fpr);
        printf("%s", buf);
    }
    //关闭文件指针
    if (fpr != NULL)
    {
        fclose(fpr);
    }
    return ERRO_MSG;
}

void testf1(const char *path/*in*/){
    char buf1[100] = { 0 };
    char buf2[100] = { 0 };
    printf("请输入键:\n");
    scanf("%s", buf1);
    printf("请输入值:\n");
    scanf("%s", buf2);
    writefile(path, buf1, buf2);
}

void main(){
    char *path = "E:/Test/CwordTest/b1.txt";
    while (1){
        int num = 0;
        printf("请输入对应的操作:\n");
        printf("添加新的键值对请按1:\n");
        printf("查询所有键值对请按2:\n");
        printf("修改键值对请按3:\n");
        scanf("%d", &num);
        switch (num)
        {
        case 1:
            testf1(path);
            break;
        case 2:
            readfile(path);
            break;
        case 3:
            testf1(path);
            break;
        default:
            break;
        }
    }
    system("pause");
}

 

posted on 2016-05-02 16:08  寒魔影  阅读(2348)  评论(0编辑  收藏  举报

导航