在C中,如何使用键值对为某些程序配置初始设置,使用以下任意或全部:纯文本configuration file,环境变量和命令行上的选项。此外,如何确定哪个方法的值超过其他两个方法中的任何一个。然后,如果已更改值,则可以选择更新配置文件。
最简单的方法是什么?如果有的话,最常用的方法是什么?是否有一个,最好是小型的开源程序,它提供了一个很好的例子来说明如何做到这一点?
答案 0 :(得分:5)
基础知识:
哪个设置源应该相互覆盖取决于应用程序,但在我看来,命令行参数&gt; <环境变量>配置文件最有意义。
以下是使用命令行覆盖环境从环境和命令行获取配置的示例:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, const char* const* argv) {
int i;
const char* myConfigVar;
// get default setting from environment
myConfigVar = getenv("MY_CONFIG_VAR");
// if the variable wasn't defined, initialize to hardcoded default
if (!myConfigVar)
myConfigVar = "default value";
// parse commandline arguments
// start at 1, because argv[0] contains the name of the program
for (i = 1; i < argc; ++i) {
if (strcmp("--my-config-var", argv[i]) == 0) {
if (i + 1 < argc)
myConfigVar = argv[i + 1];
else
printf("missing value for my-config-var argument\n");
}
}
printf("myConfigVar = '%s'\n", myConfigVar);
return 0;
}
你已经看到它很快变得非常冗长乏味,所以如果你想要的目标平台存在一个现有的库,或者至少将这种代码考虑到许多函数中,最好使用现有的库。
另一个有趣的选择是将脚本语言绑定到您的应用程序,然后您可以使您的应用程序只读取并“执行”您的设置文件,并且用户可以配置设置文件以从环境中读取一些设置,并从例如,命令行。这实际上取决于应用程序的类型和大小以及目标受众是否值得这样做。
答案 1 :(得分:5)
答案 2 :(得分:2)
对于各种格式,有大量的库用于处理配置文件解析。寻找两种流行选择的XML和INI格式。编写自定义解析器可能是一个坏主意,因为它很少或根本没有收获。 Here是一个用于解析INI文件的随机C库,XML留作练习。
设置之间的优先级通常是命令行选项覆盖任何“环境”设置。我会按照重要性的顺序建议这样的优先事项:
但是2和3可能会翻转。
答案 3 :(得分:2)
这个问题并不十分清楚。问题是“存在什么机制?”,“参数和格式的约定是什么?”,或者“我应该如何混合和匹配?”?
有几种非常标准的方式(至少在unix世界中):
要选择用于自己程序的方法,请在冻结自己的选择之前,从已接受的练习的正典中检查许多程序,阅读一些博客,阅读一些书籍......
配置文件可能是跨操作系统最便携的。
治疗可能会相当复杂。如果命令行参数可能会影响配置文件或环境变量的解释,但您仍然希望命令行取代其他机制(一个好主意),您可能需要三次传递:
在unix传统中,请查看getopt
和getopt_long
。另请考虑gengetopt
您可以通过设置用于设置环境变量的shell脚本来简化配置文件问题(但这会将您锁定为unix模型)。解析纯文本很容易和跨平台,但编写更多代码。使用标准格式和库会对用户的构建环境提出要求,但应该节省错误和混淆。
如果配置环境很复杂,将配置状态封装在可根据需要传递的结构中非常有用。这是gengetopt
采用的方法,我发现它很有用。
答案 4 :(得分:1)
对于此区域中类似Unix的设计模式,请查看Raymond的“Art Unix Programming”。它讨论了命令行参数在环境变量和配置文件上的优先级,等等。
答案 5 :(得分:1)
Lua语言的部分原因在于需要为一组工具提供定义明确的配置语言。将Lua集成为配置语言仍然非常容易。一个相当完整的例子出现在“Lua编程”一书中,该版本的旧版本可在线获取。 Chapter 25描述了使用Lua C API将Lua嵌入为配置语言,并说明了为什么要这样做。