Форум: "Основная";
Текущий архив: 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