现在的位置: 首页 > 综合 > 正文

c语言读写配置文件

2013年10月07日 ⁄ 综合 ⁄ 共 3375字 ⁄ 字号 评论关闭

     在项目里面经常会用到读取一些配置信息,而C语言有没有直接的读取配置文件的函数,这里贴出我写的代码,有兴趣的看一下,也希望能有好的建议。

      考虑到代码需要在多个项目里面运行,会对配置文件有不同的需求,这里把文件路径封装在一个struct里面,方便在里面添加一些其他的变量,头文件声明如下:

hcof.c

/******************************************************************
 * 用途: 配置文件读写                                               *
 * 作者: uehang                                                   *
 * 日期: 2013-3-28                                                *
 *****************************************************************/

#ifndef HCONF_H
#define HCONF_H

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

typedef struct h_conf{
    char file_path[200];
}HConf;

void init_conf(HConf *hconf, char *file_path);

/*
 * return: -1:fail to open file; 0: can not find the key; 1: success
 */
int get_conf_value(HConf *hconf, char *key_name, char *value);

/*
 * return: -1:fail to open file; 0: can not find the key; 1: success
 */
int set_conf_value(HConf *hconf, char *key_name, char *value);

#endif

      首先,初始化函数,对当前的情况来说,只负责把参数file_path的值传递到参数hcnf的file_path变量,这里单独写成一个函数,不仅是让get_conf_value()和set_conf_value()在调用时避免写一长串的file_path,也是方便在有特殊需求的情况下,对文件名进行检验或对文件进行预处理。

      get_conf_value()与set_conf_value()负责读写文件,由于配置文件多是在程序启动或者特殊时刻才会读取,所以没有必要一直打开文件。

hconf.c

#include "hconf.h"

void init_conf(HConf *hconf, char *file_path)
{
	int fd=open(file_path,O_RDONLY);
	if(fd>2){   //确保文件存在
		close(fd);
		strcpy(hconf->file_path,file_path);
	}else{
	    perror("can not open config file:");
	}
}

int get_conf_value(HConf *hconf, char *key_name, char *value)
{
	int res;
	int fd = open(hconf->file_path,O_RDONLY);
	if(fd > 2){
    	res = 0;
        char c;
        char *ptrk=key_name;
        char *ptrv=value;
        while((read(fd,&c,1))==1){
    	    if(c == (*ptrk)){
    	        do{
    		    ptrk ++;
		    read(fd,&c,1);
                }while(c == (*ptrk));
		if(c=='='&&(*ptrk)=='\0'){
		    while(1)
		    {
			read(fd,&c,1);
			if(c != '\n')
			{
                            (*ptrv) = c;
			    ptrv ++;
			}else{
			    (*ptrv) = '\0';
			    break;
			}
		    }
		    res = 1;
		    break;
		}else{
		    do{
			read(fd,&c,1);
		    }while(c != '\n');
		}
	    }else{
		do{
		    read(fd,&c,1);
		}while(c != '\n');
	    }
	}
	close(fd);
    }else{
	res = -1;
    }
    return res;
}

int set_conf_value(HConf *hconf, char* key_name, char *value)
{
    int res;
    int fd = open(hconf->file_path,O_RDONLY);
    if(fd > 2){
        char buf[800];  //存储文件内容
        res = 0;
        char c;
        char *ptrk=key_name;
        char *ptrv=value;
        char *ptrb=buf;
        while((read(fd,&c,1))==1){
	    *ptrb = c;
	    if(c == *ptrk){
       		do{
		    ptrb ++;
		    ptrk ++;
		    read(fd,&c,1);
		    *ptrb = c;
		}while(c == *ptrk);
		if(c == '=' && *ptrk == '\0'){//找到目标行
		    do{
			ptrb ++;
			*ptrb = *ptrv;
			ptrv ++;
		    }while(*ptrv != '\0');   //将value赋值给buf
		    while((read(fd,&c,1)) == 1 && c != '\n');//等号右边原来的内容舍弃
		    ptrb ++;
		    *ptrb = '\n';
		}else {    //非目标行全部读取
		    while((read(fd,&c,1)) == 1){
		        ptrb ++;
			*ptrb = c;
			if(c == '\n'){
			    break;
			}
		    }
		}
	    }else{        //非目标行全部读取
	        while((read(fd,&c,1)) == 1){
		    ptrb ++;
		    *ptrb = c;
		    if(c == '\n'){
		        break;
		    }
		}
	    }
	    ptrb ++;
	}
	*ptrb = '\0';  //循环结束,buf末尾置'\0'
	close(fd);
	fd=open(hconf->file_path,O_WRONLY|O_TRUNC);//截短打开文件,写入buf
	if(fd > 2){
	    write(fd,buf,strlen(buf));
	    close(fd);
	    res = 1;
	}
    }else{
	res = -1;
    }
    return res;
}

        所有打开的文件都有一个当前文件偏移量(current file offset),可以简称为 cfo。cfo 通常是一个非负整数,用于表明文件开始处到文件当前位置的字节数。读写操作通常开始于 cfo,并且使 cfo 增大,增量为读写的字节数。文件被打开时,cfo 会被初始化为 0,除非使用了 O_APPEND 。这里通过每次的read()和write()函数来改变偏移量,使定位准确。

        由于c语言中的文件是以数据流的形式来进行读写的,无法直接进行插入、删除的操作,这里把文件内容经处理后全部读取到内存里面,然后从内存写入到原文件里面,实现对文件的修改。


测试

       这里用一个简单的文件测试一下

main.c

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

#include "hconf.h"

int main()
{
    HConf *info = (HConf *) malloc(sizeof(HConf));
    init_conf(info,"./info.conf");

    char buf[20];
    get_conf_value(info,"email",buf);
    printf("email = %s --get from info\n",buf);

    set_conf_value(info,"age","115 years old");
    printf("set info:age = 115 years old\n");

    return 0;
}

结果:

           

原info.conf                                                                                               运行后info.conf

                                                    

总结

       总的来说,是实现了基本读写功能,而且只用了文件操作的open()、read()、write()这三个函数,而在测试时也发现,对中文的比较和判断会出错,若有大侠路过,也恳求指点。

抱歉!评论已关闭.