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");
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM