| imho.ws |
![]() |
|
|
|
# 1 |
|
Full Member
Регистрация: 11.12.2002
Сообщения: 864
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Задача: чтение INI-подобного файла. С поддержкой простых макросов. Например:
Код:
baseDir = c:\work resultDir = $(baseDir)\result Основное требование к синтаксису - чтобы создвать такие ini-файлы было удобно и просто. Код должен быть на С/С++. Я понял что XML дает похожие возможности, но с ним не знаком, поэтому если это возможно сделать с XML - давайте примеры. |
|
|
|
|
# 2 |
|
Full Member
Регистрация: 16.10.2002
Адрес: ArchLinux, Internet
Сообщения: 557
![]() ![]() ![]() ![]() |
по моему xml тут не причем. Трудно поверить что есть ТОЧНО такой готовый парсер. Поэтому, http://en.wikipedia.org/wiki/Yacc и вперед...
|
|
|
|
|
# 3 |
|
Full Member
Регистрация: 11.12.2002
Сообщения: 864
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Проблема в том, что я не особо программер, а тут нужен кто-то, кто имел хотя бы небольшой опыт с парсерами. Мне не сильно важен синтакс, мне нужна функционaльность
Код:
[Common] BaseDir = c:\base ResultDir = $(BaseDir)\result [Start] inputFile = $(BaseDir)\input.txt outputFile = $(ResultDir)\start_out.txt [Continue] inputFile = $([Start]outputFile) outputFile = $(ResultDir)\cont_out.txt Последний раз редактировалось crawler; 12.04.2007 в 20:01. |
|
|
|
|
# 4 |
|
Junior Member
Регистрация: 10.10.2003
Адрес: Москва
Сообщения: 136
![]() ![]() ![]() ![]() |
Если ваяешь в билдере, то полезно будет использовать объект типа TIniFile - там немножко к нему прикрутить функциональности и тебе будет самое то. Если надо без привязки к среде разработки, то смотри вот здесь: _http://www.codeproject.com/cpp/rexsearch.asp
__________________
"Самое великое достижение Америки - каждый должен голосовать". - Джордж Буш Мл.(Остин, 08.12.00). |
|
|
|
|
# 5 |
|
Member
Регистрация: 18.08.2004
Пол: Male
Сообщения: 235
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Как я понял, нужна такая процедура:
Код:
#include <stdio.h>
#include <tchar.h>
#include <windows.h>
BOOL GetString(TCHAR* fileName, TCHAR* section, TCHAR* key, // [in]
TCHAR* value, // [out]
DWORD sizeOfValue, TCHAR* commonSection = NULL) // [in]
{
//TCHAR common_section[] = _T("Common");
BOOL need_free = !commonSection;
if (need_free)
commonSection = _tcsdup(_T("Common"));
TCHAR seps[] = _T("$()"), *token, *next_token;
TCHAR inner_buffer[MAX_PATH];
// получим исходную строку
int ret_val = GetPrivateProfileString(section, key, NULL, value, sizeOfValue, fileName);
TCHAR* start_mark = NULL; // начало замещаемой конструкции
while (start_mark = _tcschr(value, _T('$')))
{
_tcscpy_s(inner_buffer, MAX_PATH, value);
value[0] = _T('\0');
start_mark += inner_buffer - value + 2;
token = _tcstok_s(inner_buffer, seps, &next_token);
while (token != NULL)
{
size_t cur_len = _tcsnlen(value, sizeOfValue);
if (token == start_mark)
{
// если [секция]имя, разбиваем их нулем [секция0имя
// и секцию читаем с первого символа
TCHAR* custom_section = NULL;
if (custom_section = _tcschr(token, _T(']')))
*custom_section = _T('\0');
ret_val = GetPrivateProfileString(
custom_section?token+1:commonSection,
custom_section?++custom_section:token,
NULL, value + cur_len, sizeOfValue - cur_len, fileName);
if (ret_val == 0)
break; // нет какого-то ключа/секции
// следующая замещаемая конструкция
start_mark = _tcschr(next_token, _T('$')) + 2;
}
else
_tcscpy_s(value + cur_len, sizeOfValue - cur_len, token);
token = _tcstok_s(NULL, seps, &next_token);
}
if (ret_val == 0)
break;
}
if (need_free)
free(commonSection);
return ret_val;
}
int _tmain(int argc, _TCHAR* argv[])
{
TCHAR ini_file[] = _T("e:\\Visual Studio Projects\\INIParser\\test.ini");
TCHAR buffer[MAX_PATH];
TCHAR common_section[] = _T("Common");
TCHAR section[] = _T("Final");
TCHAR key[] = _T("megaFile");
_putts(
GetString(ini_file, section, key, buffer, sizeof(buffer)/sizeof(TCHAR))?
buffer:_T("Error"));
return 0;
}
Приведенный код обрабатывает любое число подстановок в строке, например: Код:
[Final] part = public\release megaFile = $(ResultDir)\$([Final]part)\release.txt _http://blog.not-a-kernel-guy.com/2006/08/15/33 _http://blog.not-a-kernel-guy.com/2006/11/29/106 |
|
|
|
|
# 6 |
|
Full Member
Регистрация: 11.12.2002
Сообщения: 864
![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() |
Bishop, спасибо, ты натолкнул меня на правильный путь. Я понял что мне нужно
. В связи с этим и может кому понадобиться на будущее несколько проектов, которые облегчат жизнь:DotConf : парсер конфигурационных файлов с синтаксисом похожим на ХМЛ, на С DotConf++ : то же самое, но на С++. Сейчас довожу напильником до идеала. Nini парсер на .NET со множеством опций. Был бы на с++ , выбрал бы его. Boost.Program_options Какая-то супер крутая библиотека. я с ней не разобрался, но сам факт того что она входит в БУСТ внушает уважение. Есть еще много всякого, но они меня не устроили. к модераторам: переименуйте пожалуйста тему в "Парсер для файлов конфигурации / .cfg / .ini |
|
|