Programowanie w języku Delphi » Gotowce

Konwersja String na PAnsiChar lub PChar

  • 2012-04-23 16:00
  • 16 komentarzy
  • 5480 odsłon
  • Oceń ten tekst jako pierwszy
Nie wiem czy ten temat był już tu poruszany ale ja szukałem i nic nie znalazłem (jeszcze parę dni temu sam nie wiedziałem jak to zrobić). No więc typ PAnsiChar jest wykorzystywany przez np. procedurke ShellExecute w moduliku ShellApi i jak próbujemy uruchomić plik w formacie String (to taka przenośnia, chyba każdy ją rozumie ;-) ) no to pojawia się błąd kompilatora. Aby to przekonwertować, trzeba trochę pokombinować. Ale, i tutaj cytat wróżki chrzestnej ze Shreka 2: <quote>Wy-star-czy: </quote> :-) (jakby co to piszę z pamięci, jakieś drobrne błędy mogą się zdarzyć!)

zmienna_PAnsiChar_lub_PChar := PChar(zmienna_string);


a jeżeli ktoś lubi kombinować to proszę bardzo:

function StrToPAnsiChar(aStr: String): PAnsiChar;
var buf: array[0..1000] of Char;
    I: Integer;
begin
  for I := 0 to 1000 do 
    buf[I] := #0; { musi być zerowanie bufora, patrz info na dole }
  for I := 0 to Length(aStr) do
    begin
      buf[I] := aStr[I + 1];
      StrToPAnsiChar := buf;
    end;
end;


I co? Działa? Tak. W jaki sposób? Przeanalizujmy to...
Otóż najpierw robimy pętle for od 0 do długości zmiannej dane - 1. Tego chyba nie muszę omawiać. Jak wiecie, zmienna_string[i] jest kompatybilne ze zmienną Char. No więc do tablicy charów przypisujemy pokolei każdy znak łańcucha string, a następnie tą tablicę Char przypisujemy do typu TAnsiChar. I co? Nie ma błędu! Dlaczego? Bo TAnsiChar jest taką tabelą Charów tylko że jest to typ przekonwertowany z WinApi (C, czy tam C++). Pewnie jakby było PAnsiString to by było kompatybilne ze Stringiem... Widzicie jaki prosty sposób!

PS. Kod i sposób ściągnięty z neta, a właściwie to z forum Eksperta, ale opis jest mój własny!!!

>>>>>
Uwaga !!
begin
 for i:=0 to 1000 do buf[i]:=#0;

Wszystko ładnie tylko że w przypadku kilkukrotnego wywołania procedury w buf zostaje zapamiętana stara wartość i procedurka robi psikusy. Dopiszcie to po begin i jest wtedy OK. Trzeba zerować bufor.
Pozdrawiam SQ2HCE Mariusz

16 komentarzy

panza 2008-11-14 10:05

ekm... a dlaczego nie...?

[code]
ac: ansichar;
pc: pansichar;
s: string;

s := ac
pc := @ac[1];

[/code]

youviula 2008-08-01 16:17

Witam

Mam problem. Potrzebuje rozłożyć ciąg np: 'ala ma kota' na dynamiczna tablice char.
W efekcie chciałbym uzyskać tablicę w której każda komórka będzie zawierać poszczególne litery ciągu 'ala ma kota'

Z Góry dzięki.

brodny 2006-07-21 18:33

Ja też się przyczepię: Konwersja String na PAnsiChar lub PChar. Otóż z tego, co wiem, na razie PChar = PAnsiChar (bo Char = AnsiChar). Być może w przyszłych wersjach Char będzie aliasem na typ WideChar, ale póki co Delphi aż tak nie ubóstwia znaków wielobajtowych.

Ooni 2006-04-21 00:07

dodam że ten NULL na końcu jest bardzo istotny. Bo np: jeśli chcecie zrobić coś takiego:

  lpFileName : PChar;
  s : String;

 s:='COM1';
 lpFileName:=PChar(s);


to niestety ale portu COM nie otworzycie...

Marooned 2006-01-03 17:55

Jakoś nie pasi mi ten gotowiec.. więcej żartów niż treści, formatowanie by się jakieś przydało...

mlagrass 2006-01-03 10:43

length(dane)
, a nie
length(dane)-1

dos 2005-01-17 10:12

przeanalizowałem ten kod i to var buf: array[0..lenght(dane)+20] of char; napewno nie może działać... No bo w końcu to dane robi się w trakcie działania programu, a buf przy Create... Wygłupiłem się... Ale nie będę więcej, przygotowuje potężny artykuł

dos 2004-12-29 17:53

No i napisałem że może nie działać... No i że nie sprawdzałem... Dopiszę do artykułu tego PChara.

Wolverine 2004-12-29 17:33

<quote>var buf: array[0..lenght(dane)+20] of char;</quote>
:D łał swietny jestes :D a teraz napisz z tym jakis program

po co w ogole kombinujesz, tak jak napisal Deti PAnsiChar(string) i masz...

dos 2004-12-27 16:36

function StrToPAnsiChar(dane:string):PAnsiChar;
var buf: array[0..999999] of char;
i : integer;
begin
for i:=0 to lenght(dane)-1 do
begin
buf[i]:=dane[i+1];
StrToPAnsiChar:=buf;
end;
end;

Może być? Albo jeszcze lepiej:
function StrToPAnsiChar(dane:string):PAnsiChar;
var buf: array[0..lenght(dane)+20] of char; //to 20 to dla bezpeczeństwa :-) Nie wiem czy tak można bo nie sprawdzałem, z pamięci pisze
i : integer;
begin
for i:=0 to lenght(dane)-1 do
begin
buf[i]:=dane[i+1];
StrToPAnsiChar:=buf;
end;
end;

Wolverine 2004-12-24 14:55

a co jesli dane beda mialy wiecej niz 1000 znakow? :)

dos 2004-12-23 17:42

Ale według mojego sposobu można łatwiej operować na pojedyńczyń znakach łańcucha... :-)

Deti 2004-12-23 11:41

PAnsiChar jest wskaźnikiem na łańcuch, a wystarczy:

PCHAR(string) .. i już mamy zamienione. :)

dos 2004-12-22 19:26

Sorry, rzeczywiście. Niepotrzebna jest funkcja PAnsiCharToStr. Zaraz to wykasuje.

Wolverine 2004-12-22 18:55

<quote>function PAnsiCharToStr(dane:PAnsiChar):string;
begin
PAnsiCharToStr:=PAnsiChar(dane);
end;</quote>
Przeczytaj sam co napisales :D podajesz w parametrze PAnsiChar, rzutujesz to na PAnsiChar i przypisujesz do stringa ...

a string to P(ansi)Chara - P(ansi)Char(jakis_string), jest jeszcze funkcja StrPas, ale jest ona tylko ze wzgledow "kompatybilnosci wstecznej"

<quote>Bo TAnsiChar jest taką tabelą Charów tylko że jest to typ przekonwertowany z WinApi (C, czy tam C++).</quote>
coz, taka roznica, ze string w 1 bajcie ma zapisana jego dlugosc (aby wiadomo bylo dokad czytac) a PChar na koncu ma bajt o wartosci NULL, czyli 0, lub #0 (jak kto woli :)) Oba sa tablicami charow (bajtow)

A, to wszystko juz gdzies bylo (w faq)

dos 2004-12-22 18:45

Przyda wam się? Jak tak to piszcie!!! Jestem ciekaw...