这可能是编程时最常见的任务/问题之一; 您需要在某处存储应用程序的配置.
在我尝试创建Web服务器或其他应用程序时,我希望尽可能保持代码清洁,因为我对编程的主要兴趣是架构.这导致我希望将配置存储在文件中,无需重新编译软件即可对其进行更改.
我不是来重新发明轮子或类似的东西,所以我想做的是在C on*nix上创建一个配置阅读器.配置看起来可能与任何其他软件的配置非常相似; Apache,vsftpd,MySQL等
基本问题是:如何从文本文件中读取并有效地处理每一行(在纯C中)?我需要使用fgetc()
和处理每个字符吗?
嗯有LibConfig.
我在Wiki中找到了它
各种各样的人给出了相当不错的建议 - Pure-FTP示例很有意思.
您还应该阅读ES Raymond的TAOUP(Unix编程艺术).它有一些示例 - 大量的配置文件.它还概述了配置文件的规范习语.例如,您应该允许'#'在行的末尾开始注释,并忽略空行.如果配置文件包含您不理解的行 - 是否要忽略并继续静默,或者是否要抱怨,您还应该决定要做什么.(我更喜欢抱怨的东西;然后我知道为什么我刚刚添加的东西没有任何影响 - 而沉默忽略意味着我不知道我刚添加的条目是否有任何影响.)
另一个问题是找到配置文件.您是通过编译位置,使用环境变量覆盖的默认安装位置,还是通过其他一些魔法来实现的?确保有一个命令行选项允许绝对指定配置文件 - 甚至考虑将其作为唯一的方法.
否则,在广泛的范围内,保持简单,每个人都会更快乐.
好的,让我们点击其他部分.你需要考虑你想要的"语言".在UNIX世界中,规范版本可能是以空格分隔的文本(思考/etc/hosts
)或":"分隔文本(如/etc/passwd
).
你有几个选择,在某种意义上最简单的是使用scanf(3).再次阅读手册页以获取详细信息,但是如果行条目是类似的话
port 100
然后你会找到类似的东西
char inbuf[MAXLINE]; int val; scanf("%s %d\n", &inbuf[0], &val);
如果编写一个简单的FSA解析,可以获得更大的灵活性:从行中一次读取一个字符,并使用有限自动机来定义要执行的操作.
好的,这是一个C代码的真实例子:
/* demo-fgets -- read a "demo.text", copy to stdout with line numbers. */ #include#include #define MAXLINE 100 FILE * fp; char bufr[MAXLINE]; extern int errno ; int main(int argc, char ** argv){ int count = 0 ; if((fp = fopen("demo.text","r")) != NULL){ /* then file opened successfully. */ while(fgets(bufr,MAXLINE,fp)!=NULL){ /* then no read error */ count +=1; printf("%d: %s", /* no "\n", why? */ count, bufr); } /* fgets returned null */ if(errno != 0){ perror(argv[0]); /* argv[0]? Why that? */ exit(1); } exit(0); /* EOF found, normal exit */ } else { /* there was an error on open */ perror(argv[0]); exit(1); } }
我用这个输入文件运行它:
520 $ cat demo.text Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum aliquet augue id quam. Sed a metus. Quisque sit amet quam. Sed id ante. In egestas est non mi. Sed vel velit non elit vehicula viverra. Curabitur eget tortor in ipsum vulputate faucibus. Suspendisse imperdiet mauris at nibh. Sed interdum. Maecenas vulputate, massa vel placerat mattis, ante est tincidunt sem, in sollicitudin velit lacus non tortor. Etiam sagittis consequat nisl. Vestibulum id leo quis mauris gravida placerat. Donec aliquet justo a tortor. Etiam nisi nibh, auctor non, luctus et, aliquam vitae, metus. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nunc lacinia quam a ligula. Nulla quis nisi eu nunc imperdiet cursus. Nunc vitae nisi vitae tellus posuere sollicitudin. Nunc suscipit, dui ac interdum euismod, pede nisl varius dui, sed mattis libero mauris eu felis. Nam mattis dui eget nunc. Suspendisse malesuada, pede eget posuere pellentesque, neque eros pretium nibh, ut blandit dui leo dapibus orci. Etiam lacinia lectus at orci. Donec ligula lacus, sagittis nec, sodales et, fringilla lobortis, eros. Etiam sit amet nulla. Aliquam mollis pede id enim. Etiam ligula felis, pulvinar nec, vestibulum molestie, interdum ut, urna. Ut porta ullamcorper diam. Nullam interdum arcu. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Etiam eu enim quis sem accumsan tristique. Proin non sem. Etiam quis ante. Aenean ornare pellentesque dolor. Praesent sodales. Cras dui velit, scelerisque a, accumsan a, vestibulum in, dui. Pellentesque sed sapien. Etiam augue est, convallis eget, egestas vel, molestie id, turpis. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Cras posuere lorem eu diam. Ut ultricies velit. Nunc imperdiet suscipit mauris. Vestibulum molestie elit id risus. Phasellus et purus. Vestibulum id mauris. Fusce gravida elit quis turpis. Aliquam ut est. Sed in mauris eu nulla rhoncus suscipit. Nam id dolor sit amet turpis placerat sodales. Nunc ipsum. Quisque diam tellus, dapibus non, interdum at, aliquam sit amet, tellus. Donec non pede eget massa aliquam semper. Quisque dictum lacinia ipsum. Fusce magna purus, mattis id, commodo et, lobortis eu, arcu. Vestibulum viverra neque a nulla. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque vel felis in ligula blandit auctor. Quisque quam. Curabitur turpis. Morbi molestie augue a nisi. Nulla sollicitudin sagittis elit. Suspendisse in odio sed magna dictum vestibulum. Duis facilisis lorem eget neque. Proin sit amet urna eget velit scelerisque aliquam. Pellentesque imperdiet. Nullam sapien. Nullam placerat ipsum eget metus. Mauris ornare risus eu velit. Morbi bibendum diam in sem. Morbi aliquet nisl sit amet quam. Donec ornare sagittis nibh. Fusce ac lectus. Sed sit amet risus. Integer facilisis commodo sem. Pellentesque facilisis. Donec libero. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
有很多方法.你并不需要使用龟etc.您应该阅读stdio手册页,但规范的事情是用fopen(3)打开文件,然后使用fgets(3)读取一次读取一行.这看起来像是这样的:
#includeFILE * fp ; char bufr[MAXLINE]; if((fp = fopen(filename, "r") != NULL){ while(! feof(fp)){ fgets(bufr, MAXLINE, fp); /* Do stuff */ } } else { /* error processing, couldn't open file */ }
您还可以在Sourceforge上查看libini.
为什么你会永远从头开始编写这个代码,它已经做了这么多次; 找到一个好的F/OSS实现并使用它.
如何从文本文件中读取并有效地处理每一行
不要担心效率,读取配置文件无关紧要.寻求简单性和可维护性.