![]() |
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:
der compiler sagt immer
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; Zitat:
mfg.dominik |
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. |
Re: Probleme beim Arraygröße ändern
Zitat:
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] |
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:
und nutz das dann... kommt ziemlich aufs selbe raus ;)
type TStrArray = Array of String;
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. |
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:
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
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; |
Re: Probleme beim Arraygröße ändern
Zitat:
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 ![]() Gruß Der Unwissende [ADD] Ok, ich verweise lieber auf die hier: ![]() |
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.... |
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 |
Re: Probleme beim Arraygröße ändern
Zitat:
Und ein TStrings (memo) kann man hin wie her zuweisen. Hab ich doch oben gemacht. :gruebel: |
Re: Probleme beim Arraygröße ändern
Hallo sirius,
das meinte ich:
Delphi-Quellcode:
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.
//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; Gruß Hawkeye |
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:38 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz