配置文件的格式如下:

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*/);
//读取配置文件

函数实现:

 void trim(char *strIn, char *strOut){

     char *start, *end, *temp;//定义去除空格后字符串的头尾指针和遍历指针

     temp = strIn;

     while (*temp == ' '){
++temp;
} start = temp; //求得头指针 temp = strIn + strlen(strIn) - ; //得到原字符串最后一个字符的指针(不是'\0') while (*temp == ' '){
--temp;
} end = temp; //求得尾指针 for(strIn = start; strIn <= end; ){
*strOut++ = *strIn++;
} *strOut = '\0';
} void getValue(char * keyAndValue, char * key, char * value){ char *p = keyAndValue; p = strstr(keyAndValue, key);
if(p == NULL){
//printf("没有key\n");
return ;
} p += strlen(key);
trim(p, value); p = strstr(value, "=");
if(p == NULL){
printf("没有=\n");
return;
}
p+= strlen("=");
trim(p, value); p = strstr(value, "=");
if(p != NULL){
printf("多余的=\n");
return;
}
p = value;
trim(p, value); }
int writeCFG(const char *filename/*in*/, const char *key/*in*/, const char *value/*in*/){ FILE *pf = NULL;
char ftemp[flen] = {}, fline[] = {}, *fp; //文件缓存数组
long fsize = ;
int reg = ;
int exit = ;
int i = ; pf = fopen(filename, "r+");
if(pf == NULL){
pf = fopen(filename, "w+");
}
//获得文件大小
fseek(pf, , SEEK_END); // 将文件指针指向末尾
fsize = ftell(pf);
if(fsize > flen){
printf("文件不能超过8k\n");
reg = -;
goto end;
}
fseek(pf, , SEEK_SET); //将文件指针指向开头 //一行一行的读,如果存在key则修改value存到缓存数组中
while(!feof(pf)){
fgets(fline, , pf);
if(strstr(fline, key) != NULL && exit == )
strcpy(fline, "");
if(strstr(fline, key) != NULL && exit == ){ //判断key是否存在
exit = ;
sprintf(fline,"%s = %s\n", key, value);
} printf("fline = %s\n", fline);
strcat(ftemp, fline); }
if(exit != ){//如果不存在则把key value写入到最后一行
sprintf(fline,"%s = %s\n", key, value);
strcat(ftemp, fline);
}
if(pf != NULL){
fclose(pf);
pf = fopen(filename, "w+");
fp = (char *)malloc(sizeof(char) * strlen(ftemp) + );
strcpy(fp, ftemp);
fp[strlen(fp) - ] = EOF;
fputs(fp, pf);
if(fp != NULL){
free(fp);
fp = NULL;
}
fclose(pf);
}
end :
if(pf != NULL)
fclose(pf);
//重新创建一个以filename命名的文件
return reg;
} void readCFG(const char *filename/*in*/, const char *key/*in*/, const char **value/*out*/){ FILE *pf = NULL;
char line[] = {}, vtemp[] = {}; pf = fopen(filename, "r"); //以只读方式打开 while(!feof(pf)){
fgets(line, , pf);
getValue(line, key, vtemp);
if(strlen(vtemp) != )
break;
}
if(strlen(vtemp) != ){
*value = (char *)malloc(sizeof(char) * strlen(vtemp) + );
strcpy(*value, vtemp);
}
else
*value = NULL;
if(pf != NULL)
fclose(pf);
}

测试:

 #define filename "c:/cfg.ini"
void menu(){
printf("===========================\n");
printf("1 写入配置文件\n");
printf("2 读取配置文件\n");
printf("0 退出程序");
printf("===========================\n");
} int tWrite(){ char key[] = {}, value[] = {}; printf("请输入key:");
scanf("%s", key);
printf("请输入value:");
scanf("%s", value);
printf("\n您输入的是:%s = %s\n", key, value); return writeCFG(filename/*in*/,key/*in*/,value/*in*/);
} void tRead(){
char key[] = {}, *value; printf("请输入key:");
scanf("%s", key); readCFG(filename/*in*/,key/*in*/, &value/*out*/);
if(value == NULL){
printf("没有key\n");
return ;
}
printf("\nvalue = %s\n", value); if(value != NULL){
free(value);
value = NULL;
} }
int main(){ int choose; while(){
choose = ;
menu();
printf("请输入选择:");
scanf("%d", &choose);
switch(choose){
case :
if(tWrite() == -)
return -;
break;
case :
tRead();
break;
case :
return ;
default:
return ;
}
}
system("pause");
return ;
}

运行结果:

c语言实现配置文件的读写的更多相关文章

  1. C语言ini格式配置文件的读写

    依赖的类 /*1 utils.h *# A variety of utility functions. *# *# Some of the functions are duplicates of we ...

  2. C#+Access 员工信息管理--简单的增删改查操作和.ini配置文件的读写操作。

    1.本程序的使用的语言是C#,数据库是Access2003.主要是对员工信息进行简单的增删改查操作和对.ini配置文件的读写操作. 2.代码运行效果如下: 功能比较简单.其中在得到查询结果后,在查询结 ...

  3. 配置文件Java读写

    今天把配置文件的Bug修复了,总结一下Java配置文件如何读写 配置文件的格式 以.properties后缀结尾,内容不出现空格和双引号 //config.properties Driver=com. ...

  4. C语言编写的bmp读写程序

    C语言编写的bmp读写程序 建议先把bmp的数据存储格式了解下 <span style="font-size:16px;">#include "Windows ...

  5. java文件操作(普通文件以及配置文件的读写操作)

    转自:java文件操作(普通文件以及配置文件的读写操作) 读取普通文件 : /** * xiangqiao123欢迎你 如果对代码有疑问可以加qq群咨询:151648295 * * 读取MyFile文 ...

  6. java配置文件的读写

    最近在做一个爬虫项目时,用到了读写配置文件的方法,记录下来以后可能用的到. Properties pro = new Properties(); boolean IsFirst = true; //从 ...

  7. C语言以字符形式读写文件

    一.字符读取函数 fgetc (一).函数介绍 fgetc 是 file get char 的缩写,意思是从指定的文件中读取一个字符.函数原型为: int fgetc(FILE* fp) fp 为文件 ...

  8. wamp server 3.0.0 修改默认浏览器,软件语言和配置文件编辑器

    改默认IE浏览器为Chrome: wampmanager.conf : navigator ="C:\Program Files (x86)\Google\Chrome\Applicatio ...

  9. C语言笔记 10_文件读写&预处理器

    文件读写 上一章我们讲解了 C 语言处理的标准输入和输出设备.本章我们将介绍 C 程序员如何创建.打开.关闭文本文件或二进制文件. 一个文件,无论它是文本文件还是二进制文件,都是代表了一系列的字节.C ...

随机推荐

  1. java订单生成工具类

    欢迎来到付宗乐个人博客网站.本个人博客网站提供最新的站长新闻,各种互联网资讯. 还提供个人博客模板,最新最全的java教程,java面试题.在此我将尽我最大所能将此个人博客网站做的最好! 谢谢大家,愿 ...

  2. appcan IDE 无法 请求数据

    我们4月27号从4.0.1升级到4.0.2后,IDE本地预览get请求不到数据.但是在线打包安装到手机又是正常的. 先下载 "uexXmlHttpMgr.rar",下载链接:htt ...

  3. 简洁实用Socket框架DotNettySocket

    目录 简介 产生背景 使用方式 TcpSocket WebSocket UdpSocket 结尾 简介 DotNettySocket是一个.NET跨平台Socket框架(支持.NET4.5+及.NET ...

  4. 基于RBAC的权限框架

    RBAC权限框架(Role-Based Access Control)基于角色的权限访问控制的框架,通过用户-角色-权限的关联,非常方便的进行权限管理,在这里不再说明什么是RBAC,请自行百度. 谢谢 ...

  5. 大话 Spring Session 共享

    javaweb中我们项目稍微正规点,都会用到单点登录这个技术.实现它的方法各家有各界的看法.这几天由于公司项目需求正在研究.下面整理一下最近整理的心得. 简介 在分布式项目中另我们头疼的是多项目之间的 ...

  6. Oracle Job定时任务详解、跨数据库数据同步

    业务需求,需要与A公司做数据对接,我们公司用的Oracle,A公司用的SQL Server数据库,如何跨数据库建立连接呢?这里使用的是DBLink,不会配置的请看我的另外一篇博客:https://ww ...

  7. Gin + Vue全栈开发实战(一)

    Gin入门 本章概要 Gin简介 开发第一个Gin程序 1.1 Gin简介 Gin是用Go语言编写的一个轻量级Web应用框架,现在在各个公司包括字节跳动.bilibili等大互联网公司都得到了广泛的应 ...

  8. 从MYSQL的ibtmp1文件太大说起

    1.  啥情况呀 测试环境机器磁盘空间不足的告警打破了下午的沉寂,一群人开始忙活着删数据.但是,不久前刚清理了一波数据,测试环境在没做压测的情况下不至于短短一个月不到就涨了200G数据,于是,我悄悄的 ...

  9. k8s学习笔记

    9.deployment:声明式的升级应用 9.1.使用RC实现滚动升级 #kubectl rolling-update kubia-v1 kubia-v2 --image=luksa/kubia:v ...

  10. Salesforce LWC学习(四) 父子component交互 / component声明周期管理 / 事件处理

    我们在上篇介绍了 @track / @api的区别.在父子 component中,针对api类型的变量,如果声明以后就只允许在parent修改,son component修改便会导致报错. sonIt ...