Array of char zu string

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Array of char zu string

Beitrag von monta »

Wahrscheinlich ganz einfach, aber ich komm nicht drauf.

Wie wandel ich den ein Array of Char als typecast zu einem string um, ohne auf mode Delphi umzustellen?
Im Delphimodus ist das alles möglich, aber ich will ja schließlich objfpc benutzen ;)
Johannes

piper62
Beiträge: 131
Registriert: Sa 5. Apr 2008, 17:57
OS, Lazarus, FPC: Linux (Debian, Xubuntu), MacOS X, MS Win, Android, Web
CPU-Target: 32Bit/64Bit
Wohnort: Ulm

Re: Array of char zu string

Beitrag von piper62 »

Code: Alles auswählen

 
uses strutils;
var a_str1:array[0..64000] of char;
      v_str1:string;
// einmal hin
strpcopy(a_str1,v_str1);
// und zurück
v_str1:=strpas(a_str1);
Gruss,
Piper

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Re: Array of char zu string

Beitrag von monta »

Danke strpas hat mir gefehlt.

Um ein PChar ergänzt und nun läuft es wunderbar auch mit dyn. Array of char.
Johannes

Benutzeravatar
theo
Beiträge: 10949
Registriert: Mo 11. Sep 2006, 19:01

Re: Array of char zu string

Beitrag von theo »

Müsste auch so gehen:

v_str1:=Pchar(@a_str1);

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Re: Array of char zu string

Beitrag von monta »

Ich hab beide probiert.

Pchar(@a_str1); produziert eine andere Ausgabe als strpas. Wobei strpas die brauchbare liefert. Woran das jetzt liegt, hab ich allerdings nicht tiefer nachvollzogen.
Johannes

Benutzeravatar
theo
Beiträge: 10949
Registriert: Mo 11. Sep 2006, 19:01

Re: Array of char zu string

Beitrag von theo »

monta hat geschrieben:Ich hab beide probiert.
Pchar(@a_str1); produziert eine andere Ausgabe als strpas. Wobei strpas die brauchbare liefert. Woran das jetzt liegt, hab ich allerdings nicht tiefer nachvollzogen.
Was produziert er denn? Bei mir geht das.
Das Array muss bei 0 anfangen. Evtl. muss noch ein abschliessender Chr(0) an die letzte Position.

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Re: Array of char zu string

Beitrag von monta »

ok, mein Fehler.

Ich hab übersehen, das man zwar StrPas nur das Array übergeben muss, allerdings beim zeiger noch den Index mit benötigt:

Code: Alles auswählen

//richtig:
  writeln(StrPas(PChar(Data)));
//falsch:
  writeln(Pchar(@Data));
//richtig:
  writeln(Pchar(@Data[0]));
Johannes

Benutzeravatar
theo
Beiträge: 10949
Registriert: Mo 11. Sep 2006, 19:01

Re: Array of char zu string

Beitrag von theo »

Hmm, von mir aus gesehen ist das dasselbe.

Probier mal

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var Carr:Array[0..5] of Char=('m','o','n','t','a',#0);
begin
 Memo1.Lines.Add(Pchar(@Carr));
 Memo1.Lines.Add(Pchar(@Carr[0]));
end;
Geht das bei dir nicht? Beachte das abschliessende #0 im Array.

Warum nimmst du eig. nicht gleich String statt Array of Char?

monta
Lazarusforum e. V.
Beiträge: 2809
Registriert: Sa 9. Sep 2006, 18:05
OS, Lazarus, FPC: Linux (L trunk FPC trunk)
CPU-Target: 64Bit
Wohnort: Dresden
Kontaktdaten:

Re: Array of char zu string

Beitrag von monta »

Dein Beispiel funktioniert.

Ich nehm nicht freiwillig Array of char, aber ich hab für Cactus was von Delphi übersetzt, um Bei Audiodateien flac-Tags einlesen zu können.

Die Originalversion sah so aus:

Code: Alles auswählen

procedure TFLACfile.ReadTag( Source: TTntFileStream; bSetTagFields: boolean );
var
  i, iCount, iSize, iSepPos: Integer;
  Data: array of Char;
  sFieldID, sFieldData: string;
begin
 
  Source.Read( iSize, SizeOf( iSize ) ); // vendor
  SetLength( Data, iSize );
  Source.Read( Data[ 0 ], iSize );
  FVendor := String( Data );
 
  Source.Read( iCount, SizeOf( iCount ) ); //fieldcount
 
  FExists := ( iCount > 0 );
 
  for i := 0 to iCount - 1 do begin
      Source.Read( iSize, SizeOf( iSize ) );
      SetLength( Data , iSize );
      Source.Read( Data[ 0], iSize );
 
      iSepPos := Pos( '=', String( Data ) );
//...
Meine Version, die unter Mode objfpc funktioniert ist folgende:

Code: Alles auswählen

procedure TFLACfile.ReadTag( Source: TFileStream; bSetTagFields: boolean );
var
  i, iCount, iSize, iSepPos: Integer;
  Data: array of Char;
  sFieldID, sFieldData, sField: string;
begin
 
  Source.Read( iSize, SizeOf( iSize ) ); // vendor
  SetLength( Data, iSize );
  Source.Read( Data[ 0 ], iSize );
  FVendor := StrPas(PChar(Data)); //oder Pchar(@Data);
 
  Source.Read( iCount, SizeOf( iCount ) ); //fieldcount
 
  FExists := ( iCount > 0 );
 
  for i := 0 to iCount - 1 do begin
       Source.Read(iSize, SizeOf(iSize));
      SetLength(Data , iSize );
      Source.Read(Data[0], iSize );
      sField := Copy(StrPas(PChar(Data)), 0, iSize);
 
      iSepPos := Pos('=', sField);
 
//...
Hauptproblem war eigentlich

Code: Alles auswählen

Source.Read(Data[0], iSize );
      sField := Copy(StrPas(PChar(Data)), 0, iSize);
Ich ging davon aus, das Source.Read nur die mit iSize angegebene Länge ausliest und ich diese ohne Copy direkt übernehmen kann.
Geht allerdings nicht, da sField := StrPas(PChar(Data)); einen längeren String überträgt, mit dem zusätzlchen Copy funktioniert es so, auch wenn es wohl nicht die eleganteste Lösung ist.
Da ich davon ausging, das es wohl auch ohne Copy in Delphi funktioniert hat (siehe obigen Code) hab ich alles mögliche durchprobiert, bis ich auf Copy gekommen bin.
Johannes

Hitman
Beiträge: 512
Registriert: Mo 25. Aug 2008, 18:17
OS, Lazarus, FPC: ArchLinux x86, WinVista x86-64, Lazarus 0.9.29, FPC 2.4.1
CPU-Target: x86
Wohnort: Chemnitz

Re: Array of char zu string

Beitrag von Hitman »

theo hat geschrieben:Hmm, von mir aus gesehen ist das dasselbe.

Probier mal

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var Carr:Array[0..5] of Char=('m','o','n','t','a',#0);
begin
 Memo1.Lines.Add(Pchar(@Carr));
 Memo1.Lines.Add(Pchar(@Carr[0]));
end;
 
Geht das bei dir nicht? Beachte das abschliessende #0 im Array.

Warum nimmst du eig. nicht gleich String statt Array of Char?
Da ist ein fundamentaler Unterschied zu monta's Version: du nutzt ein statisches Array.
Ein dynamisches Array ist im Prinzip ein Record welches die Größe (Length) des Arrays und die Speicherposition des ersten Elements enthält. Das wird natürlich alles durch Compiler-Magic gehandelt. Bei einem statischen Array ist folglich der Pointer auf dessen Adresse auch der Pointer auf dessen Daten. Bei einem dynamischen hingegen ist der Pointer auf das Array selbst nur ein Pointer auf dessen interne Datenstruktur. Durch den ergänzten Index [0] referenzierst du dann allerdings den eigentlichen Inhalt und somit die Daten, an die du wirklich ran willst.

Benutzeravatar
theo
Beiträge: 10949
Registriert: Mo 11. Sep 2006, 19:01

Re: Array of char zu string

Beitrag von theo »

Klar, wusste ich ja nicht.

Dann geht's aber auch so:

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var Carr:Array of Char;
begin
Setlength(Carr,6);
Carr[0]:='m';
Carr[1]:='o';
Carr[2]:='n';
Carr[3]:='t';
Carr[4]:='a';
Carr[5]:= #0;
 
Memo1.Lines.Add(Pchar(Carr));
Memo1.Lines.Add(Pchar(@Carr[0]));
end;

Antworten