Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Probleme beim Arraygröße ändern (https://www.delphipraxis.net/83974-probleme-beim-arraygroesse-aendern.html)

dominikkv 9. Jan 2007 16:15


Probleme beim Arraygröße ändern
 
hi
ich will mir ne funktion zum teilen eines strings basteln.
ich übergebe ein array of string mittels Call-by-Reference in dem dann die teilstrings gespeichert werden.
nun sieht es aber so aus das ich die größe des arrays in der funktion nicht ändern kann...
hier mal die funktion:
Delphi-Quellcode:
function Teilen (s: String; var a: Array of String; const t: Char = ':'): boolean;
begin
result := true;
try
  setLength(a, 1); // Compiler meckert
  while Pos(t, s) > 0 do
    begin
      setlength(a, length(a)+1); // Compiler meckert
      a[high(a)] := copy(s, 1, Pos(t, s)-1);
      delete(s, 1, Pos(t, s));
    end;
  if s <> '' then
    begin
      setlength(a, length(a)+1 ); // Compiler meckert
      a[high(a)] := s;
    end;
except
  result := false;
end;
der compiler sagt immer
Zitat:

[Pascal Fehler] Unit2.pas(28): E2008 Inkompatible Typen
[Pascal Fehler] Unit2.pas(31): E2008 Inkompatible Typen
[Pascal Fehler] Unit2.pas(37): E2008 Inkompatible Typen
kann mir jemand sagen was ich falsch mach und wies richtig geht? :cheers:
mfg.dominik

SubData 9. Jan 2007 16:20

Re: Probleme beim Arraygröße ändern
 
Mach aus dem Array of String ein TStringDynArray, dann dürfte es gehen :)

Edit: Unit Types in die uses Klausel aufnehmen.

dominikkv 9. Jan 2007 16:24

Re: Probleme beim Arraygröße ändern
 
Zitat:

Zitat von SubData
Mach aus dem Array of String ein TStringDynArray, dann dürfte es gehen :)

danke für deine antwort
TStringDynArray kennt mein delphi und die OH nicht... was muss ich da einbinden?
und kann ich dann einfach ein "normales" array of string an die funktion übergeben?
mfg.dominik

[Edit]hab dein edit erst jetzt gesehen^^ ...also Types[/Edit]
[Edit]hmm...also ein array of string kann ich nicht übergeben...ansonsten klappt es. ich würd gern ein array of string übergeben...eigendlich müsste doch meine funktion von oben gehen...wo liegt da der fehler?[/Edit]

cruiser 9. Jan 2007 16:37

Re: Probleme beim Arraygröße ändern
 
Übergib einfach ein TStringDynArray res dürfte nichts anderes als die Definition eines Array of String sein, nur dass es als Typ zuweisungskompatipel ist

Alternativ deklarier dir im Interface

Delphi-Quellcode:
type TStrArray = Array of String;
und nutz das dann... kommt ziemlich aufs selbe raus ;)

edit: Dein Problem ist ja nicht das Array, sondern die Zuweisung. Deklarierst du also pro Funktion ist das Für den Compiler jeweils ein anderer Typ und die sind für gewöhnlich nicht kompatipel. Darum kommt die Meldung. Nutzt du aber sowohl im Funktionskopf als auch im aufrufenden Code ein und den selben Typen (Den du dir aus Types holst oder selber definierst) sind diese kompatibel weil sie ein und der selben Definition entstammen.

sirius 9. Jan 2007 16:59

Re: Probleme beim Arraygröße ändern
 
Wenn man ein "array of String" erstellt, sollte man sofort an eine TStringlist denken.

Hier mal ein Beispiel zum nachdenken:
Delphi-Quellcode:
procedure teilen(s:string;const a:TStringlist;const t:char=':');
begin
  a.Clear; //stringlist löschen
  a.strictdelimiter:=true; //auf Hinweis von der_Unwissende eingefügt
  a.Delimiter:=t; //Delimiter setzen
  a.DelimitedText:=s; //s wird in die Stringlist anhand des Delimiters einsortiert
end;


procedure TForm1.Button1Click(Sender: TObject);
var stringlist:TStringlist;
    s:string;
begin
  //Stringlist im Hauptspeicher erzeugen
  stringlist:=Tstringlist.create;

  //Probestring erzeugen
  s:='abc:def:ghi:2';

  //funktion starten
  teilen(s,stringlist);

  //testweise Ausgabe des Ergebnisses in einem Memo
  memo1.lines.Assign(stringlist);

  //Stringlist aus dem Hauptspeicher löschen
  stringlist.free
end;
Edit: Beachte dass meine Funktion teilen genau dasselbe macht, wie deine. Du kannst nachher die einzelnen elemente mit stringlist.strings[x] ansprechen. x liegt zwischen 0 und stringlist.count-1

Der_Unwissende 9. Jan 2007 17:13

Re: Probleme beim Arraygröße ändern
 
Zitat:

Zitat von sirius
Wenn man ein "array of String" erstellt, sollte man sofort an eine TStringlist denken.

Hier mal ein Beispiel zum nachdenken:
Delphi-Quellcode:
procedure teilen(s:string;const a:TStringlist;const t:char=':');
begin
  a.Clear; //stringlist löschen
  a.Delimiter:=t; //Delimiter setzen
  a.DelimitedText:=s; //s wird in die Stringlist anhand des Delimiters einsortiert
end;

Hi,
an sich hat sirius natürlich recht! Ein Array immer dyn. in der Größe anzupassen ist schlechter Stil (besonders beim vergrößern um 1!), hier ist der Overhead für dieses Vergrößern (neuen Speicher allozieren, altes Array reinkopieren und alten Speicher frei geben) für ein Element doch recht hoch. Insbesondere, da das Allozieren, Kopieren und Freigeben nahezu konst. viel Zeit (bei beliebiger Anzahl von Elementen) benötigt. Da ist es besser einfach gleich eine Menge mehr Elemente zu allozieren und zu verwalten, wieviel man gerade vom gesamten Array verwendet (und genau das macht die TStringList).
Die sollte jedenfalls immer erste Wahl bei dyn. Anzahl von Strings sein, genau dafür ist die da! Mittels add kannst du ein neues Element hinzufügen, die passt die Größe (bei Bedarf) selbst an.

Ein praktischer Nebeneffekt, du hast die Eigenschaften Delimiter und DelimitedText, du kannst also anhand eines Trennzeichen einen String zerlegen. Einziges Problem, die Implementierung ist etwas fehlerhaft. Dummerweise wird hier jedes Leerzeichen immer als Delimitter betrachtet, unabhängig vom eingestellten Trennzeichen. Deswegen rate ich dir dazu, zwar die TStringList oder eben einen anderen TStrings-Nachkommen zu verwenden, aber das Trennen solltest du mit einer anderen Funktion (glaube du findest hier die Hier im Forum suchenexplode) vornehmen.

Gruß Der Unwissende

[ADD]
Ok, ich verweise lieber auf die hier: Split, da wird dann auch eine TStringList zurückgegeben[/ADD]

sirius 9. Jan 2007 17:40

Re: Probleme beim Arraygröße ändern
 
Danke lieber Unwissender für die ausführliche Erläuterung. Ich vergaß, mir war da auch schon mal was aufgefallen. Wusste nicht, dass dies ein genereller Fehler ist.

Man kann natürlich Split verwenden, aber auch Borland hat darauf reagiert: siehe meine Änderung in procedure teilen.
Funktioniert allerdings nur mit BDS 2006 oder Turbo Delphi.

Edit: Ist mir übrigens aufgefallen, als ich mal den Quellcode überprüfen wollte und mir eine "eigenartige" Variable namens FStrictDelimiter in der Methode setdelimitedtext auffiel. Der bin ich dann nachgegangen....

Hawkeye219 9. Jan 2007 17:45

Re: Probleme beim Arraygröße ändern
 
Hallo,

noch eine Anmerkung: wenn bei der Deklaration der Parameter der Typ TStrings statt TStringList verwendet wird, kann man beim Aufruf der Prozedur auch TStrings-Eigenschaften (z.B. TMemo.Lines) übergeben.

Gruß Hawkeye

sirius 9. Jan 2007 17:55

Re: Probleme beim Arraygröße ändern
 
Zitat:

Zitat von Hawkeye219
Hallo,

noch eine Anmerkung: wenn bei der Deklaration der Parameter der Typ TStrings statt TStringList verwendet wird, kann man beim Aufruf der Prozedur auch TStrings-Eigenschaften (z.B. TMemo.Lines) übergeben.

Gruß Hawkeye

Tstrings würde in erster Linie ausreichen, aber Tstringlist ist von Tstrings abgeleitet und hat noch ein paar nützliche Zusatzfunktionen. Sortieren zum Beispiel.
Und ein TStrings (memo) kann man hin wie her zuweisen. Hab ich doch oben gemacht. :gruebel:

Hawkeye219 9. Jan 2007 18:09

Re: Probleme beim Arraygröße ändern
 
Hallo sirius,

das meinte ich:

Delphi-Quellcode:
//procedure teilen(s:string;const a:TStringlist;const t:char=':');
procedure teilen(const s:string;a:TStrings;t:char=':');
begin
  a.Clear; //stringlist löschen
  a.strictdelimiter:=true; //auf Hinweis von der_Unwissende eingefügt
  a.Delimiter:=t; //Delimiter setzen
  a.DelimitedText:=s; //s wird in die Stringlist anhand des Delimiters einsortiert
end;

procedure TForm1.Button1Click(Sender: TObject);
var s:string;
begin
  //Probestring erzeugen
  s:='abc:def:ghi:2';

  //funktion starten
  teilen(s,memo1.Lines);
end;
Selbstverständlich kann man auch eine TStringList übergeben, aber innerhalb der Prozedur teilen wird nicht auf die speziellen Eigenschaften dieser Klasse zugegriffen. Durch die Verwendung des Typs TStrings in der Parameterliste wird die Routine nicht unnötig eingeschränkt.

Gruß Hawkeye


Alle Zeitangaben in WEZ +1. Es ist jetzt 06:23 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz