Страница 1 из 2
разобрать секцию из ini файла
Добавлено: Вт авг 30, 2005 17:13
Parcan
потребовалось разобрать секцию из wincmd.ini [PackerPlugins]
нашел только такую функцию
//*************************
The GetPrivateProfileSection function retrieves all of the keys and values for the specified section from an initialization file. This function is provided for compatibility with 16-bit applications written for Windows. Win32-based applications should store initialization information in the registry.
Windows 95: The specified profile section must not exceed 32K.
Windows NT: The specified profile section has no size limit.
DWORD GetPrivateProfileSection(
LPCTSTR lpAppName, // address of section name
LPTSTR lpReturnedString, // address of return buffer
DWORD nSize, // size of return buffer
LPCTSTR lpFileName // address of initialization filename
);
//*************************
может уже есть у кого готовый быстрый и отработанный разбор текста lpReturnedString на массив КЛЮЧЕЙ-ЗНАЧЕНИЙ.
Добавлено: Пн сен 05, 2005 11:22
vserd
Parcan
Если программируешь в Delphi тогда воспользуйся Tstringlist.Values[]
сам так делал не однократно.
Если на C++ тогда не знаю. Потребность еще не возникала.
Добавлено: Пн сен 05, 2005 15:54
Parcan
vserd
я пишу исключительно на с++ (по работе 1с буква "с" мне уж больно нравится

), да и написать знаю как - но всеравно время надо, я человек дотошный (дева по задиаку) пока все не проверю не отстану от кода
только я видел несколько программ и плагинов где это 100% реализовано, думал кто-нить из авторов тут есть
Добавлено: Пн сен 05, 2005 16:06
D1P
На Дельфе с помощью TIniFile - как два пальца об асфальт это делается... Сосбсно, возьми дельфовский юнит, переведи на C++, там ничего сложного, и будет легко и весело. Секции в StringList читаются одной командой, а уж со стринглистом работать элементарно (это я всё про дельфю)
Добавлено: Пн сен 05, 2005 16:51
CaptainFlint
Parcan
только я видел несколько программ и плагинов где это 100% реализовано, думал кто-нить из авторов тут есть
Может и есть, да толку-то? Я, например, реализовывал у себя подобную штуку на C++, но выдернуть код не так-то просто. Я его отдельно не оформлял...
Там можно такой трюк использовать: раз строка нулём заканчивается, можно не разбивать ничего, а просто обращаться прямо по нужному указателю - всякие strlen'ы и им подобные нормально отработают. А потом полученную длину к указателю прибавляешь (может, +1 ещё) - и получаешь сразу же указатель на следующую строку, и так далее, пока не наткнёшься на повторный нолик. Релизуется элементарно, минут 10 код писать. Я бы набросал, просто на работе сидю...

Добавлено: Пн сен 05, 2005 17:36
Parcan
CaptainFlint
штуку на C++, но выдернуть код не так-то просто. Я его отдельно не оформлял
а ты объектный подход не практикуешь?
я как на втором курсе изучил, так все так и делаю у меня даже для работы с ини файлом класс есть (строчек на 15) вот надо дописать такой метод
минут 10 код писать
у меня обычно каркас по быстрому настрочишь, а потом раза в 3 дольше проверяешь все а как работает на ошибочных данных а как на полном извврате себя ведет

Добавлено: Пн сен 05, 2005 18:24
CaptainFlint
Parcan
а ты объектный подход не практикуешь?
Практикую, но не настолько же!

Лишние разбиения - понижение эффективности. Я больше кода потрачу для обёртки функции и потеряю на передаче параметров и обработке ошибок...

В общем, вот код, нашёл тут у себя копию:
Код: Выделить всё
const int BufSize = 65536;
char AllKeys[BufSize];
int CharsRead = GetPrivateProfileSection("Section", AllKeys, BufSize, FullPath);
if (CharsRead > 0)
{
char* tmp = AllKeys;
char* eq_sign;
while (*tmp)
{
if (*tmp == ';') // Пропускаем комментарии
{
tmp += strlen(tmp) + 1;
continue;
}
eq_sign = strstr(tmp, "=");
if (eq_sign != NULL)
{
*(eq_sign++) = '\0';
printf("Key: %s, value: %s\n", tmp, eq_sign);
tmp = eq_sign + strlen(eq_sign) + 1;
}
else // Пропускаем строки без знака '='
tmp += strlen(tmp) + 1;
}
}
Не знаю, мне такие простые вещи не кажутся требующими создания отдельных класов...

Добавлено: Пн сен 05, 2005 18:49
Nik
Если я все правильно понял, то можно использовать следующий алгоритм (функция проверена на Delphi 7/2005, используется в моем AmpView, работает стабильно и довольно шустро). Никаких дополнительных модулей не надо (TIniFile я вообще никогда не использую).
Код: Выделить всё
function ReadIniSection(const Section: string; FileName: string): TStringList;
const
BufSize = 16384;
var
Buffer, P: PChar;
begin
result:=TStringList.Create;
GetMem(Buffer, BufSize);
try
result.BeginUpdate;
try
result.Clear;
if GetPrivateProfileString(PChar(Section), nil, nil, Buffer, BufSize,
PChar(FileName)) <> 0 then
begin
P := Buffer;
while P^ <> #0 do
begin
result.Add(P);
Inc(P, StrLen(P) + 1);
end;
end;
finally
result.EndUpdate;
end;
finally
FreeMem(Buffer, BufSize);
end;
end;
Добавлено: Пн сен 05, 2005 19:01
CaptainFlint
Вот, кстати говоря, почему я не всё выделяю в отдельные методы: кому-то надо распарсить ключи и выделить их в массив, кому-то - в список, кому-то вообще не надо выделять, а, как у меня, сделать с каждым одну-единственную операцию, после чего выбросить и забыть (в общем случае можно организовать в виде callback-функции)... Так что, напишешь одним способом - а в следующий раз потребуется другой. А писать сразу все возможные реализации вместо одной конкретной, требующейся сейчас - на это у меня далеко не всегда хватает мужества.

Добавлено: Вт сен 06, 2005 09:19
Parcan
CaptainFlint
Nik
спасибо
CaptainFlint
кстати по коду получается что
strlen(string) дает длину не только по
\0 но и по
\n, честно говоря не знал
*(eq_sign++) = '\0';
красиво сразу не понял
Практикую, но не настолько же! Лишние разбиения - понижение эффективности. Я больше кода потрачу для обёртки функции и потеряю на передаче параметров и обработке ошибок...
ну в данном случае работа с ини-файлом нужна обычно в начале работы программы и в конце, а учитывая время обращения к файлу на диске эти затраты будут почти нулевыми, а вообще наиболее часто используемые методы обычно находятся в этом же классе... я считаю, что удобство от использования классов намного больше чем потери в вызове методов (я свои почти никогда не переписываю у меня многие классы на момент написания оказываются избыточными, но зато в другой раз ничего дописывать не приходится).
Для меня единственное что является страшным, так это виртуальные методы при наследовании и классы шаблоны при частом использовании.
Не знаю, мне такие простые вещи не кажутся требующими создания отдельных класов...
Я вот даже счетчик бы засунул в отдельный класс с одним единственным методом, хотя может это и перебор

Можно сравнить с языком описния аппаратуры VHDL или Verilog там что бы ты не описывал это устройство (хоть и маленькое) и создаешь там архитектуры - аналоги классов... так вот до ознакомления с VHDL я еще использовал порой функции, но там мне так понравилось (практически визуально объектная модель), что я и в щах стал писать так же.
ЗЫ. ладно разговорился что-то
Добавлено: Вт сен 06, 2005 09:23
Parcan
CaptainFlint
а вообще мне твой код понравился... блин делается все в 3-х строчках ... я бы написал больше кода
Добавлено: Вт сен 06, 2005 09:31
Parcan
кстати по коду получается что strlen(string) дает длину не только по \0 но и по \n, честно говоря не знал
все глянул MSDN понятно
Добавлено: Вт сен 06, 2005 10:24
CaptainFlint
Parcan
кстати по коду получается что strlen(string) дает длину не только по \0 но и по \n, честно говоря не знал
все глянул MSDN понятно
А в чём был вопрос? Насколько мне известно, никакой \n не служит ограничителем для strlen...
А, ты, видимо, сначала подумал, что отдельные ключи разделяются через \n, а не через \0?
Добавлено: Вт сен 06, 2005 12:07
Parcan
CaptainFlint
да
я прочитал описание функции самое начало - написано, что в строку будет возвращено все содержимое секции, ну и логично предположил, что строка заканчивается \n
а потом прочитал дальше, что возвращается одна или несколько нультерминированных строк и последняя имеет повторный \0
Добавлено: Чт окт 20, 2005 09:45
KindDragon
Кстати вот тут неплохой класс для работы с Ini файлами в VS
http://www.codeproject.com/cpp/ciniex.asp