(Linux平台)配置文件读写demo

很多函数是只有Linux平台有的,自知代码里面还有很多小bug,懒得优化,
还望大神们多多指正,简单读写可以直接用,欢迎测试!



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>

/**************************************************************************
*	getKeyPos()内部调用,用来在获取key值之前,
*	筛出key之前的空格
**************************************************************************/
static int isSpaceBehindKey(FILE *fp,int pos){
	char m=0;
	char cb=0;
	int newPos=0;
	fseek(fp,pos,SEEK_SET);
	fread(&cb,1,1,fp);
	while(cb == ' '){
		m++;
		fread(&cb,1,1,fp);
	}	
	(m>0)?(newPos=ftell(fp)-1):(newPos=pos);
	fseek(fp,newPos,SEEK_SET);
	return 0;
}

/************************************************************************
*	getKey() 、setKey()都调用此函数获取要操作的属性所在位置
************************************************************************/
static int getKeyPos(FILE *fp,char *p){  
	char *line = NULL,*token=NULL;
	char pEdit[100]={'\0'},lineEdit[100]={'\0'};
	size_t len = 0;
	strcpy(pEdit,p);
	strcat(pEdit,"=");
	int pos=0,jum=0;
	int ret=isSpaceBehindKey(fp,pos);
	if(ret<0){
		printf("isSpaceBehindKey err\n");
		return -1;
	}
	while ((getdelim(&line, &len,'=', fp)) != -1) {//获取‘=’之前的字符串,包括‘=’
		strncpy(lineEdit,line,strlen(p));
		strcat(lineEdit,"=");
		if((strcmp(pEdit,lineEdit))==0){
			ret = pos;
			jum=1;
			break;
		}
		getline(&line, &len, fp);
		pos=ftell(fp);
		int ret=isSpaceBehindKey(fp,pos);
		if(ret<0){
			printf("isSpaceBehindKey err\n");
			ret = -1;
		}
		memset(lineEdit,0,strlen(lineEdit));
	}
	if(!jum)ret=-1;//如果没找到,返回-1.
	free(line);
	return ret;
}

/***********************************************************************
*	上层直接调用,获取指定key的属性值,获取到的内容回填到getBuff地址
***************************************************************************/
int getKey(FILE *fp,char *p,char* getBuff){
	char Buff[100]={'\0'};
	char *line = NULL;
	int i=0;
	size_t len = 0;
	int keypos = getKeyPos(fp,p);
	if(keypos<0){
		printf("getKeyPos err:%s\n",strerror(errno));
		return -1;
	}
	getline(&line, &len, fp);
	//截取换行符之前的字符串
	strcpy(Buff,strtok(line,"\n"));
	while(Buff[i]==' '){
		i++;
	}
    strcpy(getBuff,&Buff[i]);
	free(line);
    return 0;
}

/*************************************************************
*	setKey()内部调用,用来获取删除欲修改行之后的文件大小,
*	之后可以调用truncate()改变文件大小到新的大小
****************************************************************/
static int getfilesize(FILE* fp,int keypos){
	size_t len=0;
	char *line=NULL;
	int filesize=0,pos=0;
	pos=(int)ftell(fp);
	//printf("keypos:%d\n",keypos);
	fseek(fp,keypos,SEEK_SET);
	if(-1 == (getline(&line, &len, fp))){
		printf("getline err:\n");
		return -1;
	}
	fseek(fp,0,SEEK_END);
	printf("file:%d len:%d\n",(int)ftell(fp),(int)strlen(line));
	filesize = (ftell(fp))-(strlen(line));
	fseek(fp,pos,SEEK_SET);
	free(line);
	return filesize;
}

/***************************************************************
*	setKey()内部调用,用来改变最终文件大小,并将欲修改之属性
*	写到文件尾
****************************************************************/
static int trunfile(int filesize,char *p,char* setBuff,FILE *fp,int flag){
	char Buff[100]={'\0'};
	truncate("/data/mrzhang/testfile",filesize);
	memcpy(Buff,p,strlen(p));
	strcat(Buff,"=");
	strcat(Buff,setBuff);
	(0==flag)?(fprintf(fp,"\n%s",Buff)):(fprintf(fp,"%s",Buff));
	return 0;
}

/***********************************************************
*	上层直接调用,设置属性
************************************************************/
int setKey(FILE *fp,char *p,char* setBuff){	
	size_t len = 0;
	char *line = NULL;
	char cb=0,Buff[100]={'\0'};
	int newpos=0,ret=0,filesize=0,flag=0,markkeypos=0;
	int keypos = getKeyPos(fp,p);
	if(keypos<0){//添加新属性
		memcpy(Buff,p,strlen(p));
		strcat(Buff,"=");
		strcat(Buff,setBuff);
	    fprintf(fp,"\n%s",Buff);
		goto err;
 	}
	getline(&line, &len, fp);//通过getline()操作,将文件指针移动到要设置的key所在行的下一行起始处
	filesize = getfilesize(fp,keypos);
	if(filesize<0){
		ret = -1;
		goto err;
	}
	markkeypos = keypos;
	while(-1 != (getline(&line, &len, fp))){//读取一行到line
		newpos = ftell(fp);//记录下次要读取的位置
		fseek(fp,keypos,SEEK_SET);//指定重置到上次记录的写位置
		fprintf(fp, "%s", line); //将line内容写文件
		keypos = ftell(fp);//记录下次要写的位置
		if(keypos >= filesize){//如果下次要写的位置值大于等于删除欲修改行之后文件的大小,循环将结束
			break;
		}
		fseek(fp,newpos,SEEK_SET);		
	}
	if(markkeypos>=filesize){
		fseek(fp,keypos,SEEK_SET);
		flag=1;
	}
	trunfile(filesize,p,setBuff,fp,flag);//退出循环前将要设置的属性写在文件尾
err:
	free(line);
	return ret;
}
/*int main(){
	FILE *fp;
	char *p="Q";
	char setBuff[20]="A B";
	
	char getBuff[20] = {0};
	fp = fopen("/data/mrzhang/testfile", "r+");
    if (fp == NULL)
		exit(EXIT_FAILURE);
	//setKey(fp,p,setBuff);
	printf("----------%d\n",setKey(fp,p,setBuff));
	printf("----------=%d\n",getKey(fp,p,getBuff));
	printf("%s=%s\n",p,getBuff);
	fclose(fp);
}*/






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值