Парсер файлов INI для C

Мне нужно читать/писать в файл INI на C. Для меня немного странно, что я не могу найти какой-либо стандартный способ сделать это. Каков общий способ работы с файлами INI в C?

Я предпочитаю как платформенно-независимые библиотеки, так и библиотеки синтаксического анализатора файлов INI Linux.


Это ссылка может пролить свет на этот вопрос (написана автором inih, о чем упоминал Загорулкин Дмитрий) — Я использовал minIni и остался доволен этим ..


Я знаю об этой библиотеке. Вы можете использовать ее http://code.google.com/p/inih/

2



/inih

inih (INI не изобретен здесь) — это простой синтаксический анализатор файлов .INI, написанный на C. Это всего лишь пара страниц кода, и он был разработан для маленький и простой , поэтому он подходит для встраиваемых систем. Он также более или менее совместим со стилем Python ConfigParser для файлов .INI, включая многострочный синтаксис в стиле RFC 822 и записи name: value .

Для использования просто дайте ini_parse () INI-файл, и он будет вызывать обратный вызов для каждой проанализированной пары name = value , давая вам строки для раздела, имя и значение. Это делается таким образом («стиль SAX»), потому что он хорошо работает во встроенных системах с низким объемом памяти, а также потому, что он подходит для реализации KISS.

Вы также можете вызвать ini_parse_file () для анализа непосредственно из объекта FILE * , ini_parse_string () для анализа данных из строки или ini_parse_stream () для синтаксического анализа с использованием пользовательской функции чтения в стиле fgets для пользовательского ввода-вывода.

Загрузите выпуск, просмотрите исходный код или прочитайте, как использовать inih в стиле DRY с X-макросами.

Параметры времени компиляции

Вы можете управлять различными аспектами inih с помощью определений препроцессора:

Параметры синтаксиса

  • Многострочные записи: По умолчанию inih поддерживает многострочные записи в стиле Python ConfigParser. Чтобы отключить, добавьте -DINI_ALLOW_MULTILINE = 0 .
  • Спецификация UTF-8: По умолчанию inih разрешает UTF-8 Последовательность спецификации (0xEF 0xBB 0xBF) в начале файлов INI. Чтобы отключить, добавьте -DINI_ALLOW_BOM = 0 .
  • Встроенные комментарии: По умолчанию inih разрешает встроенные комментарии с ; символ. Чтобы отключить, добавьте -DINI_ALLOW_INLINE_COMMENTS = 0 . Вы также можете указать, какой символ (символы) запускает встроенный комментарий, используя INI_INLINE_COMMENT_PREFIXES .
  • Комментарии в начале строки: По умолчанию inih позволяет как ; , так и # начинать комментарий в начале строки. Вы можете изменить это, изменив INI_START_COMMENT_PREFIXES .
  • Разрешить без значения: по умолчанию inih обрабатывает имя без значения (без = или : в строке) как ошибку. Чтобы разрешить имена без значений, добавьте -DINI_ALLOW_NO_VALUE = 1 , и inih вызовет вашу функцию-обработчик со значением NULL.

Параметры синтаксического анализа

  • Остановить при первой ошибке: по умолчанию inih продолжает синтаксический анализ остальной части файла после ошибки. Чтобы остановить анализ при первой ошибке, добавьте -DINI_STOP_ON_FIRST_ERROR = 1 .
  • Номера строк отчета: по умолчанию ini_handler обратный вызов не получает номер строки в качестве параметра. Если вам это нужно, добавьте -DINI_HANDLER_LINENO = 1 .
  • Обработчик вызовов в новом разделе: По умолчанию inih вызывает только обработчик для каждой пары name = value . Чтобы обнаружить новые разделы (например, в файле INI есть несколько разделов с одинаковыми именами), добавьте -DINI_CALL_HANDLER_ON_NEW_SECTION = 1 . Затем ваша функция-обработчик будет вызываться каждый раз, когда будет обнаружен новый раздел, с section , установленным на новое имя раздела, но name и значение установлен в NULL.

Параметры памяти

  • Стек против кучи: По умолчанию inih создает в стеке строчный буфер фиксированного размера. Чтобы выделить в куче с помощью malloc , укажите -DINI_USE_STACK = 0 .
  • Максимальная длина строки : Максимальная длина строки по умолчанию (для стека или кучи) составляет 200 байт. Чтобы изменить это, добавьте что-то вроде -DINI_MAX_LINE = 1000 . Обратите внимание, что INI_MAX_LINE должен быть на 3 больше, чем самая длинная строка (из-за r , n и NUL ).
  • Начальный размер malloc: INI_INITIAL_ALLOC указывает начальный размер malloc при использовании кучи. По умолчанию 200 байт.
  • Разрешить перераспределение: по умолчанию при использовании кучи ( -DINI_USE_STACK = 0 ) inih выделяет буфер фиксированного размера в INI_INITIAL_ALLOC байтах. Чтобы позволить этому возрасту до INI_MAX_LINE байтов, удваивая при необходимости, установите -DINI_ALLOW_REALLOC = 1 .
  • Пользовательский распределитель: по умолчанию при использовании кучи стандартные библиотеки malloc , free и realloc используются функции; чтобы использовать настраиваемый распределитель, укажите -DINI_CUSTOM_ALLOCATOR = 1 -DINI_USE_STACK = 0 ). Вы должны определить и связать функции с именами ini_malloc , ini_free и (если установлен INI_ALLOW_REALLOC ) ini_realloc , который должен иметь такие же подписи, что и функции выделения памяти stdlib.h .

Простой пример на C

 #include  #include  #include  #include "../ini.h"typedef struct {int version; const char * name; const char * email;} конфигурация; статический обработчик int (void * user, const char * section, const char * name, const char * value) {configuration *  pconfig = (конфигурация *) пользователь; #define MATCH (s, n) strcmp (section, s) == 0 && strcmp (name, n) == 0 if (MATCH ("протокол", "версия")) {pconfig  -> version = atoi (значение);} else if (MATCH ("user", "name")) {pconfig-> name = strdup (value);} else if (MATCH ("user", "email"))  {pconfig-> email = strdup (value);} else {return 0;/* неизвестный раздел/имя, ошибка */} return 1;} int main (int argc, char * argv []) {конфигурационная конфигурация; if (  ini_parse ("test.ini", обработчик, & config)  

Пример C ++

Если вы знакомы с C ++ и STL, существует также простой в использовании класс INIReader, который хранит значения в карте и позволяет Get () их:

 #include  #include "INIReader.h" int main () {INIReader  читатель ("../examples/test.ini");  if (reader.ParseError ()  

Этот простой API C ++ работает нормально, но не очень полноценный. Я не планирую больше работать над C ++ API в данный момент, поэтому, если вам нужно немного больше возможностей (например, GetSections () и GetFields () functions), посмотрите эти форки:

  • https://github.com/Blandinium/inih
  • https://github.com /OSSystems/inih

Отличия от ConfigParser

Некоторые различия между inih и модулем стандартной библиотеки Python ConfigParser:

  • Пары INI name = value, указанные выше любых заголовков разделов, рассматриваются как допустимые элементы без раздела (имя раздела — пустая строка). В ConfigParser отсутствие раздела является ошибкой.
  • Продолжение строк обрабатывается с ведущими пробелами в продолжающихся строках (например, ConfigParser). Однако вместо того, чтобы объединять продолженные строки вместе, они обрабатываются как отдельные значения для одного и того же ключа (в отличие от ConfigParser)..

Примечания к платформе

  • Windows/Win32 изначально использует имена файлов UTF-16, поэтому для обработки путей Unicode вам необходимо вызвать _wfopen () , чтобы открыть файл, а затем ini_parse_file () для его анализа; inih не включает wchar_t или обработку Unicode.

Примечания к Meson

  • meson.build не требуется для использования или компиляции inih, его основное назначение — для дистрибутивов.
  • По умолчанию Meson настроен для установки дистрибутива, но такое поведение может быть настроенным для встроенных вариантов использования:
    • с -Ddefault_library = static создаются статические библиотеки.
    • с -Ddistro_install = false библиотеки, заголовки и файлы pkg-config не будут установлены.
    • с помощью -Dwith_INIReader = false вы можете отключить сборку библиотеку C ++.
  • Все параметры времени компиляции также реализованы в Meson, их определение можно найти в файле meson_options.txt. Они не будут работать, если для distro_install установлено значение true .
  • Если вы хотите использовать inih для программ, которые могут быть поставляется в дистрибутиве, рассмотрите возможность компоновки с общими библиотеками. Записи pkg-config: inih и INIReader .
  • Если вы используете inih как подпроект Meson, вы можете использовать переменные зависимостей inih_dep и INIReader_dep . Возможно, вы захотите установить для подпроекта default_library = static и distro_install = false . Официальная оболочка предоставляется на WrapDB.
  • Для упаковщиков: если вы хотите пометить версию в файле pkg-config, вам нужно будет сделать это ниже по течению. Добавьте version: '', после тега license в функцию project () и version: meson.project_version (), после тега soversion в обеих функциях library () .

Сборка из vcpkg

Вы можете собрать и установить inih с помощью диспетчера зависимостей vcpkg:

  git clone https://github  .com/Microsoft/vcpkg.gitcd vcpkg./bootstrap-vcpkg.sh./vcpkg Integrate install./vcpkg install inih  

Порт inih в vcpkg обновляется Члены группы Майкрософт и участники сообщества. Если версия устарела, создайте проблему или запрос на вытягивание в репозитории vcpkg.

Ссылки по теме

  • Пакет Conan для inih (Conan — менеджер пакетов C/C ++)
Оцените статью
clickpad.ru
Добавить комментарий