//配置文件讀寫項目 #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"); }