Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

непонятная ошибка


zlodey ©   (2011-02-03 15:37:00) 

В ini-файл, при определенных обстоятельствах попадают строки длиной > 2048 байт. При чтении часть строки обрезается (2048 байт - ограничение TIniFile.ReadString). Написал заплатку: строки разбиваются по 65534 байта, убрал ограничение в 2048 байт. Вот код:


procedure del_keys_from_ini(AIni: TIniFile; const AScn, AIdent: string);
var
 I: Integer;
 Keys: TStrings;
 S: string;
begin
 Keys := TStringList.Create;
 try
   AIni.ReadSection(AScn, Keys);
   for I := 0 to Keys.Count - 1 do
   begin
     S := Keys[I];
     if Pos(AIdent, S) > 0 then
       AIni.DeleteKey(AScn, S);

   end;
 finally
   Keys.Free;

 end;

end;

function read_long_str_from_ini(AIni: TIniFile; const AScn, AIdent,
 ADef: string): string;

  function do_read_long_str_from_ini(const AIdent: string): string;
  var
    Buf: array[0..High(Word) - 1] of Char;
  begin
    SetString(Result, Buf, GetPrivateProfileString(PChar(AScn),
      PChar(AIdent), PChar(ADef), Buf, SizeOf(Buf), PChar(AIni.FileName)));

  end;

var
 I: Integer;
 Keys: TStrings;
 S: string;
begin
 Result := '';// <- если не установить пустую строку возникает ошибка
 Keys := TStringList.Create;
 try
   AIni.ReadSection(AScn, Keys);
   for I := 0 to Keys.Count - 1 do
   begin
     S := Keys[I];
     if Pos(AIdent, S) > 0 then
       Result := Result +
         read_long_str_from_ini(AIni, AScn, S, ADef);
         
   end;
 finally
   Keys.Free;
 end;
end;

procedure write_long_str_to_ini(AIni: TIniFile; const AScn, AIdent,
 AVal: string);
var
 L, I: Integer;
begin
 del_keys_from_ini(AIni, AScn, AIdent);
 L := Length(AVal);
 for I := 0 to L div 65534 do
   AIni.WriteString(AScn, AIdent + IntToStr(I),
     Copy(AVal, I * 65534 + 1, 65534));

end;


В большинстве случает все работает нормально, но к примеру:


procedure TLinkers.Load;
var
 I, N: Integer;
 L: TLinker_UserCustom;
 Stream: TStream;  
 S: string;  
begin
 try
   S := read_long_str_from_ini(FIniFile, const_ImportSection,
     const_ImportIdent, '');
   if S = '' then
     Exit;
   { что-то делаю }
   try
       S := read_long_str_from_ini(FIniFile, const_ImportSection,
         const_ImportCurrentIdent, '');
       if S = '' then
         Exit;
       { что-то делаю }
end;


первый раз в переменную S функция возвращает содержимое одной строки из ini-файла,
второй раз, если второй строки пусто функция должна вернуть как-бы пустую строку, но почему-то в итоге в переменной S остается значение из предыдущего вызова. Исправляется если вручную скидывать в начале функции read_long_str_from_ini Result := '';

Почему при повторном вызове не сбрасывается значение переменно S в пусто?


RWolf   (2011-02-04 09:31:00) [1]


> han_malign   (03.02.11 17:36) [9]

в D7 никаких различий между var и out не заметил.
даже хинтов при компиляции не выдаётся, если в процедуре не присвоено значение out-параметру.


Anatoly Podgoretsky   (2011-02-03 22:43:00) [2]

Одноглазая Мальвина :-)


Leonid Troyanovsky   (2011-02-03 21:46:00) [3]


> Anatoly Podgoretsky ©   (03.02.11 19:41) [10]

> Мальвину на OleVariant?

После Буратины мало кто уцелеет,
бо он тычет носом во всякие очаги.

--
Regards, LVT.


Anatoly Podgoretsky   (2011-02-03 19:41:00) [4]


> Почему целые? OleVariant :)

Мальвину на OleVariant?


han_malign   (2011-02-03 17:36:00) [5]


> procedure а(AIn:Integer; outAOut: string);
> так что в теле функции надо-таки очищать Result.

- var- в случае outдолжна магия работать(во всяком случае для интерфейсов, для строки - проверять лень)...


Ega23   (2011-02-03 16:40:00) [6]


> да и целые не могут принимать значение НУЛЛ


Почему целые? OleVariant :)


Anatoly Podgoretsky   (2011-02-03 16:37:00) [7]

> Ega23  (03.02.2011 16:07:04)  [4]

Все таки нуль 3 - 2 и минут Мальвина, равно 0, да и целые не могут принимать
значение НУЛЛ


Ega23   (2011-02-03 16:28:00) [8]


> так что в теле функции надо-таки очищать Result.

Result всегда надо очищать. Точнее, он должен быть строго определён. Хинты рулят.


RWolf   (2011-02-03 16:14:00) [9]


> zlodey   (03.02.11 15:37) 

Синтаксис
function а(AIn:Integer): string;
в дельфи эквивалентен синтаксису
procedure а(AIn:Integer; out AOut: string);
так что в теле функции надо-таки очищать Result.


Ega23   (2011-02-03 16:07:00) [10]


> Anatoly Podgoretsky ©   (03.02.11 16:03) [3]

Тогда уж NULL :)


Anatoly Podgoretsky   (2011-02-03 16:03:00) [11]

> Ega23  (03.02.2011 16:02:02)  [2]

0


Ega23   (2011-02-03 16:02:00) [12]


> Почему при повторном вызове не сбрасывается значение переменно
> S в пусто?


Буратино дали 3 яблока. 2 яблока он съел. Сколько яблок осталось у Буратино?


Anatoly Podgoretsky   (2011-02-03 15:49:00) [13]

> zlodey  (03.02.2011 15:37:00)  [0]

Наш русский програмист, на что только не пойдет лишь бы не работать!


Наверх

Титульная страница Поиск, карта сайта Написать письмо