Как инициализировать программу C, используя файл, среду и/или командную строку?

StackOverflow https://stackoverflow.com/questions/839565

Вопрос

В C, как настроить начальные настройки для некоторой программы, используя пары ключ-значение, с любым или всеми из:простой текст Файл конфигурации, переменные среды и параметры командной строки.Кроме того, как решить, какие значения метода переопределяют значения любого из двух других.Затем, если значения были изменены, при необходимости обновить файл конфигурации.

Какой самый простой способ сделать это и какие методы наиболее распространены, если таковые имеются?Существует ли программа с открытым исходным кодом (желательно небольшая), которая дает хороший пример того, как это можно сделать?

Это было полезно?

Решение

Основы:

  • Чтобы настроить вашу программу с использованием переменных среды, вы можете использовать функцию getenv, определенную в stdlib.h.
  • Чтобы настроить программу с использованием аргументов командной строки, объявите свою основную функцию, например, 'int main(int argc, const char* const* argv)' и используйте цикл для просмотра аргументов в массиве argv.Его размер задается argc.
  • Чтобы настроить вашу программу с помощью файла конфигурации, желательно выбрать какую-нибудь библиотеку, которая сделает это за вас, вместо того, чтобы изобретать еще один собственный формат файла конфигурации.Обратите внимание: в зависимости от целевой платформы существуют также библиотеки для анализа аргументов командной строки.

Какой источник настроек должен переопределять друг друга, зависит от приложения, но, по моему мнению, обычно аргумент командной строки > переменная среды > файл конфигурации имеет наибольший смысл.

Вот пример получения конфигурации из среды и командной строки с переопределением среды командной строки:

#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;
}

Вы уже видите, что очень скоро это становится очень длинным и утомительным, поэтому лучше использовать существующую библиотеку, если она существует для желаемой целевой платформы (платформ), или, по крайней мере, включить этот тип кода в ряд функций.

Еще один интересный вариант — привязать к вашему приложению язык сценариев, тогда вы сможете заставить ваше приложение только читать и «выполнять» ваш файл настроек, а пользователь сможет настроить файл настроек для чтения некоторых настроек из среды, а некоторых — из командной строки. например.Однако на самом деле это зависит от типа и размера приложения и вашей целевой аудитории, стоит ли это делать.

Другие советы

Эрик Рэймонд освещает многое из этого в разделе 10 искусства программирования Unix Очевидно, что это ориентировано на Unix, но большинство принципов можно применять в любой ОС.

Существует множество библиотек для анализа файлов конфигурации в различных форматах.Ищите форматы XML и INI — два популярных варианта.Написание собственного синтаксического анализатора, вероятно, является плохой идеей, поскольку это может потребовать много работы с небольшой выгодой или вообще без нее. Здесь — это произвольная библиотека C для анализа файлов INI, XML оставлен в качестве упражнения.

Приоритет между настройками обычно таков, что параметры командной строки переопределяют любые настройки «среды».Я бы предложил такие приоритеты в порядке убывания важности:

  1. Параметры командной строки переопределяют все
  2. Файл настроек следующий
    • Иногда разделяется между локальными файлами пользователя и глобальными файлами системы.
  3. Далее идут переменные среды

Но 2 и 3 вполне могут быть перевернутыми.

Вопрос не очень ясен.Это вопрос: «Какие механизмы существуют?», «Каковы соглашения об аргументах и ​​форматах?» или «Как мне следует смешивать и сопоставлять?»?

Есть несколько довольно стандартных способов (по крайней мере, в мире Unix):

  • переменные среды
  • файлы конфигурации
  • аргументы командной строки
  • как подмножество вышеперечисленного, файлы конфигурации, указанные в командной строке

Чтобы выбрать, какие методы использовать для вашей собственной программы, изучите много программы из канона принятой практики, прежде чем вы заморозите свой собственный выбор, прочитаете несколько блогов, прочитаете несколько книг...

Файлы конфигурации, вероятно, являются наиболее переносимыми в операционных системах.

Лечение может оказаться довольно сложным.Если аргументы командной строки могут повлиять на интерпретацию файлов конфигурации или переменной среды, но вы все равно хотите, чтобы командная строка отменяла другие механизмы (хорошая идея), вам может потребоваться три прохода:

  1. Проанализируйте командную строку и установите все переменные, которые влияют на дальнейшие настройки (скажем, какой файл конфигурации читать).
  2. Обрабатывать файлы конфигурации и переменную среды (в каком порядке?)
  3. Повторно запустите командную строку, чтобы отменить все остальные настройки.

В традиции Unix посмотрите getopt и getopt_long.Также рассмотрите такие инструменты, как gengetopt

Вы можете упростить проблему с файлом конфигурации, создав для него сценарии оболочки, которые устанавливают переменные среды (но это ограничивает вас моделью unix).Анализ простого текста прост и кросс-платформен, но требует написания большего количества кода.Использование стандартного формата и библиотеки предъявляет требования к среде сборки вашего пользователя, но позволяет избежать ошибок и путаницы.


Если ваша среда конфигурации сложна, очень полезно инкапсулировать состояние конфигурации в структуру, которую можно передавать по мере необходимости.Именно такой подход применяет gengetopt, и я нашел это полезным.

Чтобы узнать о Unix-подобных шаблонах проектирования в этой области, посмотрите на искусство Рэймонда. из Unix Программирование " ;. В нем обсуждается расстановка приоритетов аргументов командной строки над переменными среды и файлами конфигурации и т. Д.

Язык Lua частично получил свое начало из-за необходимости иметь четко определенный язык конфигурации для коллекция инструментов. Все еще довольно легко интегрировать Lua в качестве языка конфигурации. Довольно полный пример приведен в книге «Программирование на Lua», старшее издание которой доступно в Интернете. Глава 25 описывает использование API-интерфейса Lua C для встраивания Lua в качестве языка конфигурации и причины почему вы можете захотеть это сделать.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top