zoukankan      html  css  js  c++  java
  • 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
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        if (pkey == NULL)
        {
            ERRO_MSG = 2;
            printf("pkey==NULL erro msg:%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        if (pvalue == NULL)
        {
            ERRO_MSG = 3;
            printf("pvalue==NULL erro msg:%d
    ", ERRO_MSG);
            return ERRO_MSG;
        }
    
    
        //定义文件读指针
        FILE *fpwr = fopen(path, "r+");
        //判断文件是否打开成功
        if (fpwr == NULL)
        {
            ERRO_MSG = 4;
            printf("文件打开失败!erro msg:%d;文件路径是%s
    ", 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地址开始且含有''结束符的字符串复制到以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 != ''){
                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] != ''){
                    //一个一个字符进行比较
                    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
    ", 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
    ", 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
    ", ERRO_MSG);
            return ERRO_MSG;
        }
        //定义文件指针
        FILE *fpr = NULL;
        //打开文件
        fpr = fopen(path, "r");
        if (fpr == NULL)
        {
            ERRO_MSG = 2;
            printf("文件打开失败 erro msg:%d
    ", 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("请输入键:
    ");
        scanf("%s", buf1);
        printf("请输入值:
    ");
        scanf("%s", buf2);
        writefile(path, buf1, buf2);
    }
    
    void main(){
        char *path = "E:/Test/CwordTest/b1.txt";
        while (1){
            int num = 0;
            printf("请输入对应的操作:
    ");
            printf("添加新的键值对请按1:
    ");
            printf("查询所有键值对请按2:
    ");
            printf("修改键值对请按3:
    ");
            scanf("%d", &num);
            switch (num)
            {
            case 1:
                testf1(path);
                break;
            case 2:
                readfile(path);
                break;
            case 3:
                testf1(path);
                break;
            default:
                break;
            }
        }
        system("pause");
    }

  • 相关阅读:
    什么是 FutureTask?使用 ExecutorService 启动任务?
    WeakHashMap 是怎么工作的?
    什么是 Executors 框架?
    什么是原子操作?在 Java Concurrency API 中有哪些原 子类(atomic classes)?
    Java 中是如何支持正则表达式操作的?
    JDBC 能否处理 Blob 和 Clob?
    Java 中你怎样唤醒一个阻塞的线程?
    Java Concurrency API 中的 Lock 接口(Lock interface) 是什么?对比同步它有什么优势?
    为什么我们调用 start()方法时会执行 run()方法,为什么 我们不能直接调用 run()方法?
    什么是线程组,为什么在 Java 中不推荐使用?
  • 原文地址:https://www.cnblogs.com/zhanggaofeng/p/5452516.html
Copyright © 2011-2022 走看看