Здравствуйте, Corvin, Вы писали:
T_B>>Ну или поищи здесь и на www.codeproject.com -- INI-парсеров наклепано великое множество.
C>Там все под С# или MFC, — мне б кроссплатформенный...
Если кроссплатформенный -- тогда boost::program_options -- хороший вариант. Ну или ищи что-нибудь с той (линуксной) стороны.
Здравствуйте, Tuo_Bellas, Вы писали:
T_B>Здравствуйте, Corvin, Вы писали:
T_B>>>Ну или поищи здесь и на www.codeproject.com -- INI-парсеров наклепано великое множество.
C>>Там все под С# или MFC, — мне б кроссплатформенный...
T_B>Если кроссплатформенный -- тогда boost::program_options -- хороший вариант. Ну или ищи что-нибудь с той (линуксной) стороны.
T_B>Tuo_Bellas.
Здравствуйте, Corvin, Вы писали:
C>Привет всем
C>Нужен простой и удобный в использовании парсер .ini файлов — такой, — чтобы можно было делать как-нибудь так:
Здравствуйте, korzhik, Вы писали:
K>Здравствуйте, Corvin, Вы писали:
C>>Привет всем
C>>Нужен простой и удобный в использовании парсер .ini файлов — такой, — чтобы можно было делать как-нибудь так:
K>посмотри здесь
а такие ф-ции из win api не подходят?
GetPrivateProfileInt
GetPrivateProfileSection
GetPrivateProfileSectionNames
WritePrivateProfileSection
WritePrivateProfileString
WritePrivateProfileStruct
...
Здравствуйте, Corvin, Вы писали:
C>>>Нужен простой и удобный в использовании парсер .ini файлов — такой, — чтобы можно было делать как-нибудь так:
K>>посмотри здесь
Здравствуйте, sc, Вы писали:
sc>а такие ф-ции из win api не подходят? sc>GetPrivateProfileInt sc>GetPrivateProfileSection sc>GetPrivateProfileSectionNames sc>WritePrivateProfileSection sc>WritePrivateProfileString sc>WritePrivateProfileStruct sc>...
да вот я тоже на них наткнулся — решил уже забить на кроссплатформенность, но что-то они у меня не работают — я кладу вот такой test.ini
; comments
[section]
key1=value
x=24
[button32]
name="SUper Button " ; with comment
val = 23.45
в папку с проектом и пишу
TCHAR str[256];
int ret = GetPrivateProfileSectionNames(str,sizeof(str),"test.ini");
в результате в ret попадает 0, и в str ничего.. Если путь писать как "../test.ini", то же самое...
Здравствуйте, Corvin, Вы писали:
C>Нужен простой и удобный в использовании парсер .ini файлов — такой, — чтобы можно было делать как-нибудь так:
Не так давно надо было решить почти такую же задачу, только не было условия именно на .ini-файлы, подходил любой разумный формат конфигурационных файлов. Кроссплатформенность тоже требовалась. Я посмотрел несколько библиотек и вот что могу сказать.
Использует файлы в формате Record-Jar, описанном в "The Art Of UNIX Programming". Формат интересный (я "TAOP" не читал ), библиотека предоставляет доступ к нему почти как к реляционной базе данных.
Файл Record-Jar состоит из записей и полей. Поле задается в одной строке, содержащей имя, отделенное от значения двоеточием. Значение необязательно, есть значения по умолчанию. Запись — это произвольный список полей. Состав полей в разных записях базы может различаться. Записи разделяются строкой, начинающейся с "%%". В этой же строке могут быть записаны комментарии. База данных — успешно разобранный файл Record-Jar. API предоставляет доступ как на уровне записей, так и на уровне полей. Можно использовать с разными языками: C, C++, Ch, D, Ruby, Python...
Хорошая идея омрачается реализацией. Формат файла простой, а Open-RJ тащит за собой библиотеки STLSoft, которые отличаются немаленьким объемом и в некоторых случаях конфликтуют с STLPort. Например, у них сделаны какие-то загадочные обертки вокруг итераторов, которые приводят к неработоспособности стандартных алгоритмов, например, std::copy (даже в демках!). Хотя, возможно, это проблема VS6 — не вникал особо.
Компактная и симпатичная библиотека, но для сборки под Windows требуется небольшая обработка напильником. API ориентирован на plain C, так что если хочется ОО-вкусностей, надо писать обертки. Зато есть интересные возможности, например, использование переменных окружения прямо в файлах конфигурации; для расширения возможностей можно зарегистрировать функции, которые будут вызываться прямо из файла конфигурации — сейчас такая функция одна: include(filename). Формат файла тоже довольно удобный — он структурирован при помощи фигурных скобок, соответственно, допускается произвольная степень вложенности.
Разбирает файлы с XML-подобным синтаксисом. Возможно использование специальных команд в стиле препроцессора (include, define, ifdef и еще кое-что). API, опять же сишный, но считать ли это недостатком?
Отлично собирается под Windows. Проект производит хорошее впечатление. Возможно, кому-то может не понравиться "многословность" конфиг-файла: файлы в стиле ini или с фигурными скобками получаются компактнее.
Другие библиотеки
Есть еще две очень разные библиотеки с одинаковым названием libconfig.
libconfig-0.2 (LGPL) — какая-то китайская поделка (автор Zhang Le), которая, как утверждается, является портированной частью KConfig из KDE. Код очень сырой (встречаются просто зверски закомментированные куски), демки не работают. Единственное потенциальное преимущество — легковесность. Но и файлы тоже очень простые, в стиле ini. К тому же ее разработка прекращена.
libconfig-0.4(LGPL). Хороший компактный формат файла (похож на файлы libConfuse), но о кроссплатформенности не думали. Ориентирована исключительно на Unix-подобные системы. Что приятно — есть C++ API.
К сожалению, для сборки нужен flex-2.5.31, который под Windows, похоже, пока не портирован (в составе GnuWin32 его точно нет, поиск не помог).В принципе, можно перетащить, но, по-моему, оно того не стоит. Кто решит эту проблему — сообщите мне
Сейчас зашел на сайт — а там уже версия 0.5
Думайте сами, решайте сами
Мне больше других понравились spConfig и libConfuse — из них уже на вкус и цвет. libconfig (который с dystance.net), возможно, тоже неплох, но... (см. выше)
Примеры конфигурационных файлов всех описанных библиотек лежат здесь.
... << RSDN@Home 1.1.4 beta 5 rev. 395>>
Все на свете должно происходить медленно и неправильно...
C> TCHAR str[256];
C> int ret = GetPrivateProfileSectionNames(str,sizeof(str),"test.ini");
C>
C>в результате в ret попадает 0, и в str ничего.. Если путь писать как "../test.ini", то же самое...
lpFileName
[in] Pointer to a null-terminated string that specifies the name of the initialization file. If this parameter is NULL, the function searches the Win.ini file. If this parameter does not contain a full path to the file, the system searches for the file in the Windows directory.
"conraddk" <16689@users.rsdn.ru> wrote in message news:1215997@news.rsdn.ru... C>Нужен простой и удобный в использовании парсер .ini файлов — такой, — чтобы можно было делать как-нибудь так:
Вот для этих целей наилучшим образом подходит XML. Простенький SAX-парсер умещается в 20 кб кода. Готовых либ — навалом.
Здравствуйте, ssm, Вы писали:
ssm>Здравствуйте, Corvin, Вы писали:
C>>Нужен простой и удобный в использовании парсер .ini файлов — такой, — чтобы можно было делать как-нибудь так:
В общем всем спасибо за участие. В результате изысканий у меня появилось 2 метода для разбора неизвестных .ini файлов.
Один красивый и платформонезвисимый был предложен ssm здесь
. Я добавил в него тримминг пробелов из ключей/значений, распознавание комментариев и возможность парсить неизвестные заранее .ini путем вызова функции-колбэка для каждого ключа/значения (в моем случае эта функция заполняет соответствующими значениями структуру данных, из которой потом происходит вычитка стилей для элементов управления).
Второй метод я родил сам, положившись на виндовые функции GetPrivateProfileSection и GetPrivateProfileSectionNames. Кому интересно, вот код:
// Parse .ini with windows intrinsic functions
std::cout<<"Parsing the .ini with windows intrinsic functions\n";
// fill the buffer with .ini section names
TCHAR str[SECTIONNAMESBUFSIZE];
// в dir_str находится путь к файлу .ini
ret = GetPrivateProfileSectionNames(str,sizeof(str),dir_str.c_str());
if (ret==(sizeof(str)-2))
{
_tprintf(TEXT("GetPrivateProfileSectionNames failed. The buffer is too small"));
return 0;
}
TCHAR* sec_ptr = str;
// fill the key_val_pair buffer with keys/values for each section
TCHAR key_val_pair[KEYVALBUFSIZE];
TCHAR* key_val_ptr;
// сюда будут класться найденные значения
std::string section;
std::string key;
std::string value;
while(*sec_ptr!=0)
{
GetPrivateProfileSection(sec_ptr,key_val_pair,sizeof(key_val_pair),dir_str.c_str());
key_val_ptr=key_val_pair;
while(*key_val_ptr!=0)
{
char* div=strstr(key_val_ptr,"=");
if (div!=NULL)
{
*div=0;
section.assign(sec_ptr);
key.assign(key_val_ptr);
value.assign(div+1);
/* сюда вставляем код, который будет делать необходимое с именем секции, ключем и значением. */
}
*div='=';
key_val_ptr+=strlen(key_val_ptr);
key_val_ptr++;
}
sec_ptr +=strlen(sec_ptr);
sec_ptr++;
}
C>> Нужен простой и удобный в использовании парсер .ini файлов — такой, — C>> чтобы можно было делать как-нибудь так:
S> Вот для этих целей наилучшим образом подходит XML. Простенький S> SAX-парсер умещается в 20 кб кода. Готовых либ — навалом.
C>>Нужен простой и удобный в использовании парсер .ini файлов — такой, — чтобы можно было делать как-нибудь так:
dad>есть самовписный парсер основанный на callback вызовах (типа SAX для xml) dad>void on_comment(char*); dad>void on_section(char*); dad>void on_value(char*,char*);
dad>нужен?