разобрать секцию из ini файла

Только для тех, кто пишет плагины под Total Commander. Обмен опытом, решение проблем.

Модераторы: d-view, Моторокер, Avada, CaptainFlint, Nik

Аватара пользователя
Parcan
Сообщения: 399
Зарегистрирован: Ср дек 15, 2004 16:39
Откуда: Russian

разобрать секцию из ini файла

Сообщение 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 на массив КЛЮЧЕЙ-ЗНАЧЕНИЙ.
vserd
Сообщения: 118
Зарегистрирован: Вт апр 26, 2005 16:54

Сообщение vserd »

Parcan
Если программируешь в Delphi тогда воспользуйся Tstringlist.Values[]
сам так делал не однократно.
Если на C++ тогда не знаю. Потребность еще не возникала.
Аватара пользователя
Parcan
Сообщения: 399
Зарегистрирован: Ср дек 15, 2004 16:39
Откуда: Russian

Сообщение Parcan »

vserd
я пишу исключительно на с++ (по работе 1с буква "с" мне уж больно нравится :) ), да и написать знаю как - но всеравно время надо, я человек дотошный (дева по задиаку) пока все не проверю не отстану от кода
только я видел несколько программ и плагинов где это 100% реализовано, думал кто-нить из авторов тут есть
Аватара пользователя
D1P
Сообщения: 2987
Зарегистрирован: Пн дек 20, 2004 18:30
Откуда: Тбилиси
Контактная информация:

Сообщение D1P »

На Дельфе с помощью TIniFile - как два пальца об асфальт это делается... Сосбсно, возьми дельфовский юнит, переведи на C++, там ничего сложного, и будет легко и весело. Секции в StringList читаются одной командой, а уж со стринглистом работать элементарно (это я всё про дельфю)
Аватара пользователя
CaptainFlint
Сообщения: 6239
Зарегистрирован: Вт дек 14, 2004 22:34
Контактная информация:

Сообщение CaptainFlint »

Parcan
только я видел несколько программ и плагинов где это 100% реализовано, думал кто-нить из авторов тут есть
Может и есть, да толку-то? Я, например, реализовывал у себя подобную штуку на C++, но выдернуть код не так-то просто. Я его отдельно не оформлял...
Там можно такой трюк использовать: раз строка нулём заканчивается, можно не разбивать ничего, а просто обращаться прямо по нужному указателю - всякие strlen'ы и им подобные нормально отработают. А потом полученную длину к указателю прибавляешь (может, +1 ещё) - и получаешь сразу же указатель на следующую строку, и так далее, пока не наткнёшься на повторный нолик. Релизуется элементарно, минут 10 код писать. Я бы набросал, просто на работе сидю... :)
Аватара пользователя
Parcan
Сообщения: 399
Зарегистрирован: Ср дек 15, 2004 16:39
Откуда: Russian

Сообщение Parcan »

CaptainFlint
штуку на C++, но выдернуть код не так-то просто. Я его отдельно не оформлял
а ты объектный подход не практикуешь?
я как на втором курсе изучил, так все так и делаю у меня даже для работы с ини файлом класс есть (строчек на 15) вот надо дописать такой метод
минут 10 код писать
у меня обычно каркас по быстрому настрочишь, а потом раза в 3 дольше проверяешь все а как работает на ошибочных данных а как на полном извврате себя ведет :)
Аватара пользователя
CaptainFlint
Сообщения: 6239
Зарегистрирован: Вт дек 14, 2004 22:34
Контактная информация:

Сообщение 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;
	}
}
Не знаю, мне такие простые вещи не кажутся требующими создания отдельных класов... :)
Почему же, ё-моё, ты нигде не пишешь "ё"?
Аватара пользователя
Nik
Сообщения: 583
Зарегистрирован: Сб янв 01, 2005 13:00
Откуда: Киров
Контактная информация:

Сообщение 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;
Аватара пользователя
CaptainFlint
Сообщения: 6239
Зарегистрирован: Вт дек 14, 2004 22:34
Контактная информация:

Сообщение CaptainFlint »

Вот, кстати говоря, почему я не всё выделяю в отдельные методы: кому-то надо распарсить ключи и выделить их в массив, кому-то - в список, кому-то вообще не надо выделять, а, как у меня, сделать с каждым одну-единственную операцию, после чего выбросить и забыть (в общем случае можно организовать в виде callback-функции)... Так что, напишешь одним способом - а в следующий раз потребуется другой. А писать сразу все возможные реализации вместо одной конкретной, требующейся сейчас - на это у меня далеко не всегда хватает мужества. :D
Аватара пользователя
Parcan
Сообщения: 399
Зарегистрирован: Ср дек 15, 2004 16:39
Откуда: Russian

Сообщение Parcan »

CaptainFlint
Nik
спасибо

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

ЗЫ. ладно разговорился что-то
Аватара пользователя
Parcan
Сообщения: 399
Зарегистрирован: Ср дек 15, 2004 16:39
Откуда: Russian

Сообщение Parcan »

CaptainFlint
а вообще мне твой код понравился... блин делается все в 3-х строчках ... я бы написал больше кода
Аватара пользователя
Parcan
Сообщения: 399
Зарегистрирован: Ср дек 15, 2004 16:39
Откуда: Russian

Сообщение Parcan »

кстати по коду получается что strlen(string) дает длину не только по \0 но и по \n, честно говоря не знал
все глянул MSDN понятно
Аватара пользователя
CaptainFlint
Сообщения: 6239
Зарегистрирован: Вт дек 14, 2004 22:34
Контактная информация:

Сообщение CaptainFlint »

Parcan
кстати по коду получается что strlen(string) дает длину не только по \0 но и по \n, честно говоря не знал
все глянул MSDN понятно
А в чём был вопрос? Насколько мне известно, никакой \n не служит ограничителем для strlen...
А, ты, видимо, сначала подумал, что отдельные ключи разделяются через \n, а не через \0?
Аватара пользователя
Parcan
Сообщения: 399
Зарегистрирован: Ср дек 15, 2004 16:39
Откуда: Russian

Сообщение Parcan »

CaptainFlint
да
я прочитал описание функции самое начало - написано, что в строку будет возвращено все содержимое секции, ну и логично предположил, что строка заканчивается \n
а потом прочитал дальше, что возвращается одна или несколько нультерминированных строк и последняя имеет повторный \0
KindDragon
Сообщения: 1
Зарегистрирован: Чт окт 20, 2005 09:43

Сообщение KindDragon »

Кстати вот тут неплохой класс для работы с Ini файлами в VS
http://www.codeproject.com/cpp/ciniex.asp
Ответить