Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];

Вниз

Функция копирования PChar в string   Найти похожие ветки 

 
MetalFan ©   (2006-10-16 17:57) [0]

что необходимо:
1) копировать содержимое string в Pchar
2) выделять/перевыделять память под PChar
3) очищать PChar, если длинна string = 0;

вот написана такая функция
function SetPChar( var APChar: PChar; const ACopyString: string): PChar;
 var
   lLenStr: Integer;
 begin
   Result := nil;
   lLenStr := Length(ACopyString);
   if (APChar = nil) and ( lLenStr= 0) then Exit;
   if lLenStr = 0 then
   begin
      FreeMem( APChar{, 0});
      APChar := nil;
   end
   else
   begin
     ReallocMem( APChar, lLenStr + 1);
     //Result := StrLCopy(APChar, PChar(ACopyString), lLenStr);
     CopyMemory( APChar, @ACopyString[1], lLenStr);
     APChar[lLenStr] := #0;
   end;
   Result := APChar;
 end;

оцените ее правильность %) что-то никак не соображу, есть ли тут косяки...


 
Desdechado ©   (2006-10-16 18:03) [1]

var p:Pchar;
s:String;

s:=String(p);
p:=PChar(s);


 
MetalFan ©   (2006-10-16 18:08) [2]

а происходит ли при это копирование содержания s и з.
если p - внешнияя переменная, а s внутренняя, то после оконачния процедуры, где объявлена s, p будет указывать в... на... короче не туда)
или нет?


 
Eraser ©   (2006-10-16 18:08) [3]

> [1] Desdechado ©   (16.10.06 18:03)


> s:=String(p);

s := p;
UniqueString(s);


> p:=PChar(s);


p := PChar(s);


 
MetalFan ©   (2006-10-16 18:33) [4]

мм... и что, весь функционал в [0] оказывается ненужным?! )


 
Ketmar ©   (2006-10-16 18:40) [5]

>[4] MetalFan(c) 16-Oct-2006, 18:33
>мм... и что, весь функционал в [0] оказывается ненужным?! )
угу. "наука умеет много гитик" (ц) %-)


 
Leonid Troyanovsky ©   (2006-10-16 18:43) [6]


> MetalFan ©   (16.10.06 18:08) [2]

> если p - внешнияя переменная, а s внутренняя, то после оконачния
> процедуры, где объявлена s, p будет указывать в... на...
>  короче не туда)


Конечно, в никуда.
Самое простое - поменять ролями s & p, т.е., пусть p - внутренняя.
Ну, а освобождать строку просто: s := ""

--
Regards, LVT.


 
MetalFan ©   (2006-10-16 19:04) [7]

нет, функция должна однозначно копировать содержимое входной string  в pchar, чтобы дальнейшая судьба string"а никак не влияла на резульирующий pchar.

ладно, вопрос тот же: нет ли ошибок в функции в [0]?.
просто интересно мнение...


 
Ketmar ©   (2006-10-16 19:09) [8]

на:
function SetPChar (var aPChar: PChar; const aCopyString: string): PChar;
var
 lLenStr: Integer;
begin
 lLenStr := Length(aCopyString);
 ReallocMem(aPChar, lLenStr);
 if lLenStr > 0 then Move(aCopyString[1], aPChar^, lLenStr+1);
 result := aPChar;
end;


 
MetalFan ©   (2006-10-16 19:12) [9]


> Ketmar ©   (16.10.06 19:09) [8]

а #0 в конце разве будет? или в string"е тоже #0 в кноце "висит"?


 
Ketmar ©   (2006-10-16 19:12) [10]

>[9] MetalFan(c) 16-Oct-2006, 19:12
>а #0 в конце разве будет? или в string"е тоже #0 в кноце "
>висит"?
rtfm.


 
Ketmar ©   (2006-10-16 19:13) [11]

натурально, справедливо только для {$H+}.


 
MetalFan ©   (2006-10-16 19:30) [12]

с этим
> Ketmar ©   (16.10.06 19:09) [8]
вместо этого [0] проэкт просто "умирает" с AV сразу после вызова...


 
Ketmar ©   (2006-10-16 19:33) [13]

>[12] MetalFan(c) 16-Oct-2006, 19:30
>вместо этого [0] проэкт просто "умирает" с AV сразу после
>вызова...
ищи у себя баг.

{$APPTYPE CONSOLE}

function SetPChar (var aPChar: PChar; const aCopyString: string): PChar;
var
 lLenStr: Integer;
begin
 lLenStr := Length(aCopyString);
 ReallocMem(aPChar, lLenStr);
 if lLenStr > 0 then Move(aCopyString[1], aPChar^, lLenStr+1);
 result := aPChar;
end;

var
 s: string;
 p: PChar;
begin
 p := nil; s := "test";
 SetPChar(p, s); WriteLn(""", p, """);
 s := "t1";
 SetPChar(p, s); WriteLn(""", p, """);
 s := "";
 SetPChar(p, s); if p > nil then WriteLn("!");
end.


всё работает.


 
Loginov Dmitry ©   (2006-10-16 19:51) [14]

Ketmar ©   (16.10.06 19:33) [13]
ReallocMem(aPChar, lLenStr);


Единичку к lLenStr было бы неплохо приплюсовать, имхо


 
Palladin ©   (2006-10-16 19:51) [15]


> [13] Ketmar ©

Это как? Резервируешь Length, а Move делаешь на Length+1 ? ай ай ай... :)


> всё работает.

Ага, "по встречке тоже можно ехать" (с) :)


 
MetalFan ©   (2006-10-16 20:03) [16]

с учетом след.изменений валиться все перестало %)
var
  lLenStr: Integer;
 begin
  lLenStr := Length(aCopyString);

  if lLenStr > 0 then
  begin
   ReallocMem(aPChar, lLenStr+1);
   Move(aCopyString[1], aPChar^, lLenStr+1);
  end
  else
    ReallocMem(aPChar, 0);
  result := aPChar;


 
Ketmar ©   (2006-10-16 20:03) [17]

ай. ай. ай. каюсь. посыпаю тыкву пеплом. больше не буду спросонья код давать! таки налажал. код прошу считать недействительным. %-)


 
Ketmar ©   (2006-10-16 20:04) [18]

зыж не зря я свои проекты начинаю писать только часа через 4 после того, как проснусь. %-)


 
MetalFan ©   (2006-10-16 20:09) [19]

2 Ketmar ©  [17,18]
да ладно, ерунда)
спасибо за помощь в оптимизации кода!


 
Leonid Troyanovsky ©   (2006-10-16 20:10) [20]


> MetalFan ©   (16.10.06 19:04) [7]

> string  в pchar, чтобы дальнейшая судьба string"а никак
> не влияла на резульирующий pchar.


Обычно в этих случаях поступают так:

Допустим, что p - указатель на буфер достаточного размера,
скажем, a: array [0..MAX_BUF] of Char

Тогда нам достаточно сделать StrPCopy(a, s).
Хотя, конечно, предпочтительней StrPLCopy.

Если такого массива нет, то для начала, распределим
буфер (StrAlloc, GetMem), как минимум Length(s)+1 байт.
Ну, а далее - StrP(L)Copy.

Когда в оной строке более нет нужды делаем StrDispose/FreeMem.

Больше, собс-но, ничего не нужно.
Хотя, конечно, вышеописанное легко сделать и с помощью Move.

Главное, что нет никакой необходимости писать некую функцию,
которая объединит распределение буфера и копирование в него,
бо от этого возникает одна лишь путаница.

--
Regards, LVT.


 
MetalFan ©   (2006-10-16 20:10) [21]

а, ну да, вот что в итоге у меня получилось:
function SetPChar( var APChar: PChar; const ACopyString: string): PChar;
 var
  lLenStr: Integer;
 begin
  lLenStr := Length(aCopyString);
  if lLenStr > 0 then
    inc(lLenStr);
  ReallocMem(aPChar, lLenStr);
  if lLenStr > 0 then
   Move(aCopyString[1], aPChar^, lLenStr);
  result := aPChar;
end;


 
MetalFan ©   (2006-10-16 20:12) [22]

Leonid Troyanovsky ©   (16.10.06 20:10) [20]
вне функции имеем TList, в котором хранятся таким образом выделяемые PChar"ы...


 
Ketmar ©   (2006-10-16 20:13) [23]

>[21] MetalFan(c) 16-Oct-2006, 20:10
> if lLenStr > 0 then inc(lLenStr);
угу. вот это-то я и забыл. %-) похмеляццо надо чаще. %-)


 
Leonid Troyanovsky ©   (2006-10-16 20:20) [24]


> MetalFan ©   (16.10.06 20:12) [22]

> вне функции имеем TList, в котором хранятся таким образом
> выделяемые PChar"ы...


Для этого обычно используют TStringList.
Если, вдруг, потребуются PChar делают PChar(Strings[i])

> function SetPChar( var APChar: PChar; const ACopyString:

Не надо в функции распределять память.
Возьми за правило, и волосы у тебя сохранятся гораздо дольше.

--
Regards, LVT.


 
MetalFan ©   (2006-10-16 21:43) [25]


> Для этого обычно используют TStringList.

есть необходимость использовать TList)
но спасибо за совет ;)


 
Eraser ©   (2006-10-16 23:43) [26]

в догонку:
зачем вообще упали этот PChar в Делфи... не зря есть намного более удобный типа - string. С ним и надо работать, а PChar - только для Win-API ф-ий, и то, чаще всего, можно не явно использовать.


 
icWasya ©   (2006-10-17 09:51) [27]

>>зачем вообще упали этот PChar в Делфи
А действительно, для чего понадобилось использовать и то и другое??


 
Anatoly Podgoretsky ©   (2006-10-17 10:05) [28]


> А действительно, для чего понадобилось использовать и то
> и другое??

В Дельфи PChar использовать не требуется. String полностью совместим с PChar

> только для Win-API ф-ий, и то, чаще всего, можно не явно
> использовать.

И там не требуется, а если функция возращает PChar, то никому не запрещено сделать S := PChar



Страницы: 1 вся ветка

Форум: "Основная";
Текущий архив: 2006.11.26;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.52 MB
Время: 0.043 c
15-1162787285
Че
2006-11-06 07:28
2006.11.26
В Ираке повесили Ху Ваше отношение ?


1-1161005590
id
2006-10-16 17:33
2006.11.26
Передача массива в процедуру в кач-ве var параметра.


15-1162572442
Jus
2006-11-03 19:47
2006.11.26
Восстановить файлы после форматирования HDD


3-1159009804
alexandrine
2006-09-23 15:10
2006.11.26
Как посадить базу Paradox7 на сетку?


2-1162874303
Steep
2006-11-07 07:38
2006.11.26
MS SQL Server 2000





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский