c語言實現配置文件的讀寫

配置文件的格式如下:

key1 = value1

key2 = value2

  .

  .

  .

名值對以一個=鏈接,一條記錄以換行符分割

頭文件:

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

函數原型:

復制代碼
void trim(char *strIn, char *strOut);//去除字符串首位空格void getValue(char * keyAndValue, char * key, char * value);
//根據key得到valueint writeCFG(const char *filename/*in*/, const char *key/*in*/, const char *value/*in*/);
//寫入配置文件void readCFG(const char *filename/*in*/, const char *key/*in*/, const char **value/*out*/);
//讀取配置文件
復制代碼

函數實現:

復制代碼
  1 void trim(char *strIn, char *strOut){
  2 
  3     char *start, *end, *temp;//定義去除空格后字符串的頭尾指針和遍歷指針
  4 
  5     temp = strIn;
  6 
  7     while (*temp == ' '){
  8         ++temp;
  9     }
 10 
 11     start = temp; //求得頭指針
 12 
 13     temp = strIn + strlen(strIn) - 1; //得到原字符串最后一個字符的指針(不是'\0')
 14 
 15     while (*temp == ' '){
 16         --temp;
 17     }
 18 
 19     end = temp; //求得尾指針
 20 
 21 
 22     for(strIn = start; strIn <= end; ){
 23         *strOut++ = *strIn++;
 24     }
 25 
 26     *strOut = '\0';
 27 }
 28 
 29 void getValue(char * keyAndValue, char * key, char * value){
 30 
 31     char *p = keyAndValue;
 32 
 33     p = strstr(keyAndValue, key);
 34     if(p == NULL){
 35         //printf("沒有key\n");
 36         return ;
 37     }
 38 
 39     p += strlen(key);
 40     trim(p, value);
 41 
 42     p = strstr(value, "=");
 43     if(p == NULL){
 44         printf("沒有=\n");
 45         return;
 46     }
 47     p+= strlen("=");
 48     trim(p, value);
 49 
 50     p = strstr(value, "=");
 51     if(p != NULL){
 52         printf("多余的=\n");
 53         return;
 54     }
 55     p = value;
 56     trim(p, value);
 57 
 58 }
 59 int writeCFG(const char *filename/*in*/, const char *key/*in*/, const char *value/*in*/){
 60 
 61     FILE *pf = NULL;
 62     char ftemp[flen] = {0}, fline[1024] = {0}, *fp;    //文件緩存數組
 63     long fsize = 0;
 64     int reg = 0;
 65     int exit = 0;
 66     int i = 0;
 67 
 68     pf = fopen(filename, "r+");
 69     if(pf == NULL){
 70         pf = fopen(filename, "w+");
 71     }
 72     //獲得文件大小
 73     fseek(pf, 0, SEEK_END); // 將文件指針指向末尾
 74     fsize = ftell(pf);
 75     if(fsize > flen){
 76         printf("文件不能超過8k\n");
 77         reg = -1;
 78         goto end;
 79     }
 80     fseek(pf, 0, SEEK_SET); //將文件指針指向開頭
 81 
 82     //一行一行的讀,如果存在key則修改value存到緩存數組中
 83     while(!feof(pf)){
 84         fgets(fline, 1024, pf);
 85         if(strstr(fline, key) != NULL && exit == 1)
 86             strcpy(fline, "");
 87         if(strstr(fline, key) != NULL && exit == 0){ //判斷key是否存在
 88             exit = 1;
 89             sprintf(fline,"%s = %s\n", key, value);
 90         }
 91         
 92         printf("fline = %s\n", fline);
 93         strcat(ftemp, fline);
 94         
 95     }
 96     if(exit != 1){//如果不存在則把key value寫入到最后一行
 97         sprintf(fline,"%s = %s\n", key, value);
 98         strcat(ftemp, fline);
 99     }
100     if(pf != NULL){
101         fclose(pf);
102         pf = fopen(filename, "w+");
103         fp = (char *)malloc(sizeof(char) * strlen(ftemp) + 1);
104         strcpy(fp, ftemp);
105         fp[strlen(fp) - 1] = EOF;
106         fputs(fp, pf);
107         if(fp != NULL){
108             free(fp);
109             fp = NULL;
110         }
111         fclose(pf);
112     }
113     end :
114         if(pf != NULL)
115             fclose(pf);
116     //重新創建一個以filename命名的文件
117     return reg;
118 }
119 
120 void readCFG(const char *filename/*in*/, const char *key/*in*/, const char **value/*out*/){
121 
122     FILE *pf = NULL;
123     char line[1024] = {0}, vtemp[1024] = {0};
124 
125     pf = fopen(filename, "r"); //以只讀方式打開
126     
127     while(!feof(pf)){
128         fgets(line, 1024, pf);
129         getValue(line, key, vtemp);
130         if(strlen(vtemp) != 0)
131             break;
132     }
133     if(strlen(vtemp) != 0){
134         *value = (char *)malloc(sizeof(char) * strlen(vtemp) + 1);
135         strcpy(*value, vtemp);
136     }    
137     else
138         *value = NULL;
139     if(pf != NULL)
140         fclose(pf);
141 }
復制代碼

測試:

復制代碼
 1 #define filename "c:/cfg.ini"
 2 void menu(){
 3     printf("===========================\n");
 4     printf("1 寫入配置文件\n");
 5     printf("2 讀取配置文件\n");
 6     printf("0 退出程序");
 7     printf("===========================\n");
 8 }
 9 
10 int tWrite(){
11     
12     char key[1024] = {0}, value[1024] = {0};
13 
14     printf("請輸入key:");
15     scanf("%s", key);
16     printf("請輸入value:");
17     scanf("%s", value);
18     printf("\n您輸入的是:%s = %s\n", key, value);
19 
20     return writeCFG(filename/*in*/,key/*in*/,value/*in*/);
21 }
22 
23 void tRead(){
24     char key[1024] = {0}, *value;
25 
26     printf("請輸入key:");
27     scanf("%s", key);
28 
29     readCFG(filename/*in*/,key/*in*/, &value/*out*/);
30     if(value == NULL){
31         printf("沒有key\n");
32         return ;
33     }
34     printf("\nvalue = %s\n", value);
35 
36     if(value != NULL){
37         free(value);
38         value = NULL;
39     }
40 
41 }
42 int main(){
43     
44     int choose;
45     
46     while(1){
47         choose = 0;
48         menu();
49         printf("請輸入選擇:");
50         scanf("%d", &choose);
51         switch(choose){
52             case 1:
53                 if(tWrite() == -1)
54                     return -1;
55                 break;
56             case 2:
57                 tRead();
58                 break;
59             case 0:
60                 return 0;
61             default: 
62                 return 0;
63         }
64     }
65     system("pause");
66     return 0;
67 }
復制代碼

運行結果:

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/383987.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/383987.shtml
英文地址,請注明出處:http://en.pswp.cn/news/383987.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Educational Codeforces Round 73 (Rated for Div. 2)

A 很簡單的一個模擬&#xff0c;只要前面的數字有兩個以上就能合成后面的&#xff0c;我們進行一遍合成看能不能出現2048就可以了。 #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<iostream> #include&…

數據鏈路層: HDLC

一. 協議機 發送方和接收方. 同時有限狀態機把協議形式化為一個四元組 (S,M,I,T), 其中你S表示進程和信道可能進入的集合, M 表示數據幀的狀態, I 表示進程的初始狀態, T 表示兩兩狀態之間的轉化. 每個系統狀態可以分為發送狀態, 接受狀態和信道狀態. 把狀態用一個點進行表示,…

Miller_Rabin算法

為了測試一個大整數是不是素數&#xff0c;我們不能夠使用傳統的測試是否有因子的方法&#xff0c;因為那樣的時間復雜度至少也是O(n)O(n)O(n)&#xff0c;空間復雜度是O(n)O(n)O(n)&#xff08;使用線性篩數法&#xff09;&#xff0c;時間復雜度還好說&#xff0c;空間復雜度…

bob-tong 字符串函數之Strtok()函數

https://www.cnblogs.com/Bob-tong/p/6610806.html Strtok()函數詳解&#xff1a; 該函數包含在"string.h"頭文件中 函數原型&#xff1a; char* strtok (char* str,constchar* delimiters ); 函數功能&#xff1a; ??切割字符串&#xff0c;將str切分成一個個子…

數據鏈路層:SLIP(串型線路IP) PPP(點對點協議)

SLIP 沒有差錯控制, 傳輸時必須知道對方IP, 傳輸使用于低速業務 19.2k.應用非常受限 PPP協議 1. PPP協議功能 處理錯誤檢測 支持多協議(IP, IPX, DECnet 等) 連接時允許協商 IP 地址 允許身份驗證 2. PPP 的組成 串型鏈路上封裝數據報, 即支持異步鏈路也支持面向 比特…

Honeycomb——BFS

【題目描述】 傳送門 【題目分析】 看起來很復雜好像還要建圖什么的&#xff0c;其實直接在原圖上BFS就可以了&#xff0c;設置一下方向數組&#xff0c;然后直接跑就可以了。 【AC代碼】 #include<cstdio> #include<cstring> #include<algorithm> #inc…

C語言中strspn()函數和strcspn()函數的對比使用

C語言strspn()函數&#xff1a;計算字符串str中連續有幾個字符都屬于字符串accept 頭文件&#xff1a;#include <string.h> strspn() 函數用來計算字符串 str 中連續有幾個字符都屬于字符串 accept&#xff0c;其原型為&#xff1a; size_t strspn(const char *str, con…

Codeforces Round #587 (Div. 3)

A 只要每兩個都不一樣就可以&#xff0c;一旦出現兩個一樣的就改一個。 #include<cstdio> #include<cstring> #include<algorithm> #include<climits> #include<cctype> #include<queue> #include<set>using namespace std;typede…

信道分配 以太網

1.頻分復用 將信道分為多個頻帶, 用戶得到某個頻帶后,在通信的過程中, 自始至終都都占用這個信道.即頻分復用中, 所有用戶同時占用不同頻帶的信道 2. 時分信道 將時間劃分為一段一段的等長時分復用幀, 每個用戶在不同時間占用相同的數據幀 3. CSMA/CD 載波監聽多點接入/碰撞…

strpbrk函數

http://blog.csdn.net/tommy_wxie/article/details/7554332 函數原型&#xff1a;extern char *strpbrk(char *str1, char *str2) 參數說明&#xff1a;str1待比較的字符串&#xff0c;str2為指定被搜索的字符串。 所在庫名&#xff1a;#include <string.h> …

網絡層網絡層服務及其 IP 地址

ARP 協議功能 將 IP 地址通過廣播(一個網段, 不能跨路由器), 目標 MAC 地址是FFFFFFFF 解析目標IP地址的 MAC 地址. IP 協議 網絡層的一個協議, 是一個協議的統稱, 包括 ARP(地址解析協議) 協議, ICMP(網絡控制報文協議) 協議, IGMP(網際組管理協議) 協議. 其中 ICMP 和 IG…

隨機生成1024個數,存入一段內存,用指針實現獲取1024個數的最大數地址,最小數地址

http://blog.csdn.net/itcastcpp//details/39277193 題目&#xff1a;隨機生成1024個數&#xff0c;存入一段內存&#xff0c;用指針實現獲取1024個數的最大數地址&#xff0c;最小數地址&#xff0c;具體實現如下&#xff1a; [cpp] view plaincopy #include<stdlib.h> …

UVa11134

【題目分析】 覺得是一道挺考驗貪心掌握程度的題目&#xff0c;我就算知道是要用貪心而且肯定和區間有關&#xff0c;肯定要進行一下排序什么的我還是沒有找到合適的貪心策略。 經過大佬的博客后我才明白如何進行貪心。 如果沒有任何提示看這道題&#xff0c;首先&#xff0…

傳輸層:IP 地址解析 路由轉發

IP 地址與硬件地址 1. 地址解析 通過IP地址將其如何轉換為 MAC 地址.解決同一個局域網上的主機或路由的 IP 地址和硬件地址的映射問題. 即以太網上除了主機還有路由. 即如果發出的請求所有的主機都沒有做出相應, 那么該以太網上的路由會對其做出響應. (1) 以太網內部主機與…

UVa11582

一個數學問題,一旦出現循環確定循環節以后就能解決問題啦. 加上一個快速冪取模.需要注意的是數據范圍是264,所以必須用unsigned long long才能解決問題. 覺得板子還是要會自己寫,否則不同的題目具體有一些小的改變就會束手無策. 還有就是發現如果每次初始化數組的話就會超時,所…

輸入一個單向鏈表,輸出該鏈表中倒數第K個結點

http://blog.csdn.net/itcastcpp/article/details/39274891//尹成 單鏈表操作 #include <iostream> using namespace std; class LinkList;struct LinkNode { public:LinkNode(int value 0):m_value(value),pNext(NULL){}~LinkNode(){pNext NULL;}friend class LinkList…

網絡層:構成超網(CIDR)

CIDR構成超網 CIDR消除了原來的傳統的 A,B, C, D類地址, 使用了各種網絡前綴來代替原來分類地址中的網絡號和子網號, IP 地址由原來的三級分類又變成了兩級分類. 其中網絡號和子網號是一個隨機的長度. 其中 CIDR 也可以使用 / 的形式來表示, 其中在 / 前面寫上網絡前綴的位數.…

UVa12169

我們可以暴力枚舉a,然后通過x1和x3確定b的值&#xff0c;然后確定其他的數字&#xff0c;一旦出現錯誤就放棄這組解。 關鍵問題就在于如何通過a,x1,x3確定b的值 x2 ( x1 * a b) % M x3 ( x2 * a b ) % M ( ( x1 * a b ) % M * a b ) % M x3 - k * M x1 * a % M * a %…

尹成 雙循環鏈表

今天&#xff0c;我們一起用C寫一個雙鏈表&#xff0c;具體代碼如下&#xff1a; DoubleList.h具體內容如下&#xff1a; [cpp] view plaincopy #include "NodeList.h" template<typename Type> class DoublyList{ public: DoublyList() :head(ne…

堆的基本操作

堆的數據結構 對于堆, 有最大堆和最小堆, 在定義一個堆的時候用一個數組表示堆, 同時為了方便定義堆的大小, 用一個 size 表示堆的有效元素, 同時為了區別最大堆和最小堆, 我們用一個函數指針表示這個堆是最大堆還是最小堆. typedef int (*Compare)(HeapType parent, HeapTyp…