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得到value

int 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 }
复制代码

运行结果:

  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
纯c读写ini配置文件 用c/c++读写ini配置文件有不少第三方的开源库,如iniparser、libini、rwini、UltraLightINIParser等,但都不理想,往往代码较大、功能较弱、 接口使用不方便。尤其在大小写处理、前后空格、各种注释、跨平台换行符支持、带引号字符串处理、无section操作、原格式保持等方面存在问题。 现将本人精心制作的ini读写程序源码奉献给大家,纯c编写,简洁好用。支持windows和linux。 主要特点: 1、支持;和#注释符号,支持行尾注释。 2、支持带引号'或"成对匹配的字符串,提取时自动去引号。引号可带其它引号或;#注释符。 3、支持无section或空section(名称为空)。 4、支持10、16、8进制数,0x开头为16进制数,0开头为8进制。 5、支持section、key或=号前后带空格。 6、支持\n、\r、\r\n或\n\r换行格式。 7、不区分section、key大小写,但写入时以新串为准,并保持其大小写。 8、新增数据时,若section存在则在该节最后一个有效数据后添加,否则在文件尾部添加。 9、支持指定key所在整行删除,即删除该键值,包括注释。 10、可自动跳过格式错误行,修改时仍然保留。 11、修改时保留原注释:包括整行注释、行尾注释(包括前面空格)。 12、修改时保留原空行。以上三点主要是尽量保留原格式。 不足之处: 1、不支持单key多value(逗号分割),只能一次性提取后自行处理。 2、不支持同名重复section和key。(重复section可视为错误,重复key则可能造成分歧) 3、不能提取所有section或key名称。 使用只需两个文件inirw.h、inirw.c,另有测试程序和工程文件,支持windows和linux。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值