如何使用文件,环境和/或命令行初始化C程序?

时间:2009-05-08 12:27:15

标签: c configuration initialization ini

在C中,如何使用键值对为某些程序配置初始设置,使用以下任意或全部:纯文本configuration file,环境变量和命令行上的选项。此外,如何确定哪个方法的值超过其他两个方法中的任何一个。然后,如果已更改值,则可以选择更新配置文件。

最简单的方法是什么?如果有的话,最常用的方法是什么?是否有一个,最好是小型的开源程序,它提供了一个很好的例子来说明如何做到这一点?

6 个答案:

答案 0 :(得分:5)

基础知识:

  • 要使用环境变量配置程序,可以使用stdlib.h中定义的getenv函数。
  • 要使用命令行参数配置程序,请将主函数声明为'int main(int argc,const char * const * argv)',并使用循环来遍历argv数组中的参数。它的大小由argc。
  • 给出
  • 要使用配置文件配置程序,最好选择一些为您执行此操作的库,而不是发明另一种自定义配置文件格式。请注意,根据您定位的平台,还有用于解析命令行参数的库。

哪个设置源应该相互覆盖取决于应用程序,但在我看来,命令行参数&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)

雷蒙德在The Art of Unix Programming的第10节中介绍了很多内容。显然这是以Unix为中心的,但大多数原则都适用于任何操作系统。

答案 2 :(得分:2)

对于各种格式,有大量的库用于处理配置文件解析。寻找两种流行选择的XML和INI格式。编写自定义解析器可能是一个坏主意,因为它很少或根本没有收获。 Here是一个用于解析INI文件的随机C库,XML留作练习。

设置之间的优先级通常是命令行选项覆盖任何“环境”设置。我会按照重要性的顺序建议这样的优先事项:

  1. 命令行选项会覆盖任何内容
  2. 接下来是设置文件
    • 有时会在用户的本地文件和系统全局文件之间进行拆分
  3. 接下来是环境变量
  4. 但是2和3可能会翻转。

答案 3 :(得分:2)

这个问题并不十分清楚。问题是“存在什么机制?”,“参数和格式的约定是什么?”,或者“我应该如何混合和匹配?”?

有几种非常标准的方式(至少在unix世界中):

  • 环境变量
  • 配置文件
  • 命令行参数
  • 作为上述命令行中指定的配置文件的子集

要选择用于自己程序的方法,请在冻结自己的选择之前,从已接受的练习的正典中检查许多程序,阅读一些博客,阅读一些书籍......

配置文件可能是跨操作系统最便携的。

治疗可能会相当复杂。如果命令行参数可能会影响配置文件或环境变量的解释,但您仍然希望命令行取代其他机制(一个好主意),您可能需要三次传递:

  1. 解析命令行并设置影响进一步设置的任何变量(说明要读取的配置文件)
  2. 处理配置文件和环境变量(什么顺序?)
  3. 重新运行命令行以覆盖所有其他设置。

  4. 在unix传统中,请查看getoptgetopt_long。另请考虑gengetopt

    等工具

    您可以通过设置用于设置环境变量的shell脚本来简化配置文件问题(但这会将您锁定为unix模型)。解析纯文本很容易和跨平台,但编写更多代码。使用标准格式和库会对用户的构建环境提出要求,但应该节省错误和混淆。


    如果配置环境很复杂,将配置状态封装在可根据需要传递的结构中非常有用。这是gengetopt采用的方法,我发现它很有用。

答案 4 :(得分:1)

对于此区域中类似Unix的设计模式,请查看Raymond的“Art Unix Programming”。它讨论了命令行参数在环境变量和配置文件上的优先级,等等。

答案 5 :(得分:1)

Lua语言的部分原因在于需要为一组工具提供定义明确的配置语言。将Lua集成为配置语言仍然非常容易。一个相当完整的例子出现在“Lua编程”一书中,该版本的旧版本可在线获取。 Chapter 25描述了使用Lua C API将Lua嵌入为配置语言,并说明了为什么要这样做。