很多函数是只有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); }*/
(Linux平台)配置文件读写demo
最新推荐文章于 2021-05-12 10:55:13 发布