在 C 语言中,如何使用键值对配置某些程序的初始设置,其中任何或全部:纯文本配置文件、环境变量和命令行上的选项。此外,如何确定哪种方法的值会覆盖其他两种方法的值。然后,如果值已更改,则可选择更新配置文件。
最简单的方法是什么?如果有的话,最被接受的方法是什么?是否有一个最好是小型的开源程序来提供一个很好的例子来说明如何做到这一点?
在 C 语言中,如何使用键值对配置某些程序的初始设置,其中任何或全部:纯文本配置文件、环境变量和命令行上的选项。此外,如何确定哪种方法的值会覆盖其他两种方法的值。然后,如果值已更改,则可选择更新配置文件。
最简单的方法是什么?如果有的话,最被接受的方法是什么?是否有一个最好是小型的开源程序来提供一个很好的例子来说明如何做到这一点?
基础:
哪个设置源应该相互覆盖取决于应用程序,但在我看来,通常命令行参数 > 环境变量 > 配置文件最有意义。
这是从环境和命令行获取配置的示例,命令行覆盖环境:
#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;
}
您已经看到它很快就会变得非常冗长和乏味,因此如果您想要的目标平台存在一个现有的库,那么最好使用现有的库,或者至少将这种代码分解为许多函数。
另一个有趣的选择是将脚本语言绑定到您的应用程序,然后您可以让您的应用程序只读取和“执行”您的设置文件,并且用户可以配置设置文件以从环境读取一些设置,从命令行读取一些设置,例如。这实际上取决于应用程序的类型和大小以及您的目标受众是否值得这样做。
Eric Raymond 在The Art of Unix Programming第 10 节中涵盖了很多内容显然这是以 Unix 为中心,但大多数原则都可以应用于任何操作系统。
有大量的库用于处理各种格式的配置文件解析。寻找两种流行的选择 XML 和 INI 格式。编写自定义解析器可能不是一个好主意,因为它可能需要大量工作而收效甚微或毫无收获。这是一个用于解析 INI 文件的随机 C 库,XML 留作练习。
设置之间的优先级通常是命令行选项覆盖任何“环境”设置。我会建议这样的优先级,按重要性降序排列:
但是 2 和 3 很可能会颠倒过来。
这个问题不是很清楚。问题是“存在哪些机制?”、“参数和格式的约定是什么?”还是“我应该如何混合和匹配?”?
有几种非常标准的方法(至少在 unix 世界中):
要选择用于您自己的程序的方法,请在冻结您自己的选择、阅读一些博客、阅读一些书籍之前从公认的实践规范中检查许多程序……
配置文件可能是跨操作系统最可移植的。
治疗可能会变得相当复杂。如果命令行参数可能会影响配置文件或环境变量的解释,但您仍然希望命令行推翻其他机制(一个好主意),您可能需要三遍:
在 unix 传统中,请查看getopt
and getopt_long
。还要考虑像这样的工具gengetopt
您可以通过制作设置环境变量的 shell 脚本来简化配置文件问题(但这会将您锁定在 unix 模型中)。解析纯文本很容易且跨平台,但需要编写更多代码。使用标准格式和库对用户的构建环境提出了要求,但应该可以避免错误和混乱。
如果你的配置环境比较复杂,把配置状态封装在一个结构体中,可以根据需要进行传递是非常有帮助的。这是 采用的方法gengetopt
,我发现它很有用。