![]() |
Delphi-Version: 5
Problem mit procedure Split()
Hallo
Ich hoffe ich bin hier richtig. Ich hab ein kleines problem mit der Funktion Split() was ist den hier falsch?, wieso bekomme ich das ganze nicht gesplittet?
Delphi-Quellcode:
program uragan;
var list: TStringList; s : string; i : integer; procedure Split(const Delimiter: Char; Input: string; const Strings: TStrings); begin Strings.Clear; Strings.Delimiter := Delimiter; Strings.DelimitedText := Input; end; begin list := TStringList.create; s := 'blabla' + HStr('00') + 'blabla2' + HStr('00') + 'blabla3' + HStr('00') + 'blabla4' + HStr('00') + 'blabla5' + HStr('00') ; Split(HStr('00'), s, list); for i := 0 to list.count-1 do begin ShowMessage(list[i]); end; end. |
AW: Problem mit procedure Split()
Was kommt den raus?
|
AW: Problem mit procedure Split()
Guten Abend,
was macht denn HStr('00')? Ist es das gleiche wie #0? Warum sind Strings in der Paramterliste der Prozedur split als const deklariert? Grüße Klaus |
AW: Problem mit procedure Split()
changed..
gruss |
AW: Problem mit procedure Split()
Zitat:
array0 = blabla array1 = ?? ist frei, wahrscheinlich #0 mehr kommt nicht wenn ich Split string ändere, zb auf ","dann klappt es, es muss aber HStr('00')bzw #0 sein |
AW: Problem mit procedure Split()
Hallo,
es kommen nicht *zwei Arrays*, sondern zwei Einträge in einer TStringList. Einer gleicht 'blabla' und einer ist ein Leerstring. Mach einen Breakpoint auf Strings.DelimitedText := Input; und steppe mal mit F7 durch. Dann wird Dir klar, was passiert. Kurz gesagt: #0 geht halt nicht. Antwort1) der Delimiter darf bei dieser Vorgehensweise nicht #0 sein. Antwort2) eine TStringList für diesen Zweck zu verwenden ist super praktisch und super Performance fressend. Mir hat eine Funktion auf Stackoverflow ganz gut gefallen:
Delphi-Quellcode:
HTH
procedure TForm1.Button1Click(Sender: TObject);
const MYDELIMITER = #0; var s : string; sTok: string; i : integer; function GetTok(const Line: string; const Delim: Char; const TokenNum: Byte): string; { LK Nov 8, 2009 - Reoptimized using PChars instead of calls to Pos and PosEx } { See; http://stackoverflow.com/questions/1694001/is-there-a-fast-gettoken-routine-for-delphi } var I, CurToken: Integer; PLine, PStart: PChar; begin CurToken := 1; PLine := PChar(Line); PStart := PLine; for I := 1 to length(Line) do begin if PLine^ = Delim then begin if CurToken = TokenNum then break else begin CurToken := CurToken + 1; inc(PLine); PStart := PLine; end; end else inc(PLine); end; if CurToken = TokenNum then SetString(Result, PStart, PLine - PStart) else Result := ''; end; begin s := 'blabla' + MYDELIMITER + 'blabla2' + MYDELIMITER + 'blabla3' + MYDELIMITER + 'blabla4' + MYDELIMITER + 'blabla5' + MYDELIMITER ; i := 1; sTok := GetTok(s, MYDELIMITER, i); while ('' <> sTok) do begin ShowMessage(sTok); inc(i); sTok := GetTok(s, MYDELIMITER, i); end; end; |
AW: Problem mit procedure Split()
Deine Funktion kommt nur mit kurzen Strings klar und ist vom Aufwand O(n^2), weil für jedes Token immer von Anfang an gesucht wird. Ob das Schneller ist, bezweifle ich mal ganz stark.
Im Gegensatz dazu ist die TStringList-Geschichte sehr viel mächtiger, denn sie kommt mit allen Stringtypen und mit in Gänsefüschen eingeschlossenen Texten klar, z.B. wird
Delphi-Quellcode:
in drei Strings ("a", "b,c" und "d") aufgeteilt.
a,"b,c",d
Der Code von TStringlist sieht auch ganz schön flott aus. |
AW: Problem mit procedure Split()
..alternativ könntest Du auch mal diese
![]() ![]() Grüße Klaus |
AW: Problem mit procedure Split()
Wer eine Stringliste als Splitter nutzt, der sollte sich von #0 als Trenner verabschieden.
Alles, was intern PChar nutzt oder eine Kompatibilität zu diesem bietet, das kann nich genutzt werden. #0 = Textende also weiter macht die Stringliste auch nicht |
AW: Problem mit procedure Split()
Es scheint sich aber um eine C-Stringliste zu handeln. Dort wird m.W. #0 als Trenner verwendet
|
AW: Problem mit procedure Split()
Zitat:
Zitat:
Zitat:
Aber es ist im Endeffekt alles Geschmacksache und der beste Code ist der, der den Job erledigt und vom Kunden bezahlt wird ;-) |
AW: Problem mit procedure Split()
Nur leider ist die TStringList, bzw. alle Strings-Nachfahren, beim Input, nur auf einen einzelnen String ausgelegt und keine C-Stringliste.
Delphi-Quellcode:
procedure CStringArrayToStringList(const StringArray: String; SL: TStrings);
var P: PChar; begin SL.BeginUpdate; try SL.Clear; P := PChar(StringArray); if (P^ <> #0) or ((P + 1)^ <> #0) then repeat SL.Add(P); Inc(P, StrLen(P) + 1); until P = #0; finally SL.EndUpdate; end; end; [unnützes Wissen] die ResourceStrings werden auch so verwaltet ... jeweils 16 in einem solchen StringArray |
AW: Problem mit procedure Split()
Hast du mal versucht, deiner Liste die Eigenschaft "StrictDelimiter" auf true zu setzen, bevor zu splittest:
Delphi-Quellcode:
procedure Split(const Delimiter: Char; Input: string; const Strings: TStrings);
begin Strings.Clear; Strings.Delimiter := Delimiter; Strings.StrictDelimiter:= True; // <--- hier Strings.DelimitedText := Input; end; Zitat:
|
AW: Problem mit procedure Split()
In Delphi 5 gab es noch keinen StrictDelimiter.
|
AW: Problem mit procedure Split()
Zitat:
komisch, bekomme ERROR: Unknown type: 'PChar' Also wie ich sehe geht es nicht auf diese weise. Hab versucht mit Pos() gibt auch 0 aus :( Ist es möglich alle #0 im string zu löschen? oder auf was anderes zu verändern? |
AW: Problem mit procedure Split()
PChar ist eigentlich in der System-Unit deklarier, welche automatisch eingebunden wird :gruebel:
Du könntest versuchen die #0 durch einen anderen trenner zu ersetzen (StringReplace()) |
AW: Problem mit procedure Split()
Also wenn ich einen PChar habe, und der zeigt auf Strings, die mit #0 voneinander getrennt sind, und zusätzlich habe ich noch die Gesamtlänge des Speicherbereiches, dann liegt es doch nahe, einfach mal durchzulaufen und ein ARRAY OF PCHAR oder eine TList zu erstellen, wenn man auf ein #0 stößt
Delphi-Quellcode:
Voraussetzung: Hinter dem letzten String ist ein #0.
Function SplitByNullChar (P : PChar; N : Integer) : TList;
Var I : Integer; C : Char; Begin Result := TList.Create; Result.Add(P); For I :=1 to N-1 Do begin C := P^; Inc(P); If C=#0 then Result.Add(P); End; End; Danach stehen in der TList lauter PChars, die jeweils auf das erste Zeichen des Tokens zeigen. Terminiert wird dieser String ja durch ein #0, nämlich den nächsten Delimiter. |
AW: Problem mit procedure Split()
Klingt elegant (ausser dass man höllisch aufpassen muss, wer die TList wieder freigibt). Aber soweit ich das verstanden habe MUSS es eine TStringList sein (Aufgabenstellung?). So gesehen läge es auch nahe, eine eigene Ableitung zu machen und im Setter
Delphi-Quellcode:
die #0 extra freundlich zu behandeln.
TMyStrings.SetDelimitedText
|
AW: Problem mit procedure Split()
Function SplitByNullChar (P : PChar; N : Integer) : TList;
PChar gibt es nicht :( |
AW: Problem mit procedure Split()
Zitat:
gruss |
AW: Problem mit procedure Split()
Weil PChar schon ein Pointer auf einen oder mehrere Chars ist?
Wenn es PChar nicht gibt, dann stimmt irgendwas nicht und man sollte erstmal dieses Problem beheben. |
AW: Problem mit procedure Split()
Zitat:
Ist mir schon klar.. Aber anscheinend hat er kein PChar oder steht ihm nicht zur verfügung. Zitat:
gruss |
AW: Problem mit procedure Split()
Zitat:
|
AW: Problem mit procedure Split()
Liste der Anhänge anzeigen (Anzahl: 1)
wie siehts aus wenn man das ganze so macht?
weiß jemand wieso das ganze nicht klappt?
Delphi-Quellcode:
var
list2: TStringList; res : string; i : integer; procedure Split(const Delimiter: Char; Input: string; Strings: TStrings); var setstring : string; StringsTemp : TStringList; begin StringsTemp := TStringList.create; Strings.Clear; while setstring <> '' do begin StringsTemp.Clear; StringsTemp.Delimiter := Delimiter; StringsTemp.DelimitedText := Input; Strings.Add(StringsTemp[0]); setstring := StringsTemp[0]; Delete(Input,0,Length(StringsTemp[0])+1); end; end; begin list2 := TStringList.create; res := 'test1'+#0+'test1'+#0+'test1'+#0 ; Split(#0, res, list2); for i := 0 to list2.count-1 do begin ShowMessage(list2[i]); end; end. EDIT:: Hab das ganze versucht in eine datei abzuspeichern
Code:
Es wird in der Datei angezeigt
62 6c 61 62 6c 61 00 0d 0a
62 6c 61 62 6c 61 32 00 0d 0a 62 6c 61 62 6c 61 33 00 0d 0a
Code:
blabla
blabla2 blabla3 Wenn ich per TStringList.LoadFromFile die selbe datei lade, dann wird nur der erste eintrag abgerufen, und danach ist stop. D.h. nach wiederholtem abspeichern auf die selbe datei ist es nur noch:
Code:
62 6c 61 62 6c 61 00
Code:
echt komisch :(
blabla
PS: Datei liegt im Anhang, falls jemand probieren möchte |
AW: Problem mit procedure Split()
Das liegt an der 0, das ist in Delphi nun einmal das Stringende-Zeichen, wurde aber bereits mehrfach gesagt.
|
AW: Problem mit procedure Split()
Zitat:
|
AW: Problem mit procedure Split()
Ist es nicht möglich die Funktion Trim() so umzubauen, dass es alle #0 löscht?
|
AW: Problem mit procedure Split()
Trim entfernt doch jetzt schon alle führenden und nachfolgenden #0-en ? :gruebel:
|
AW: Problem mit procedure Split()
Entfernt doch Leerzeichen oder? also #20
|
AW: Problem mit procedure Split()
Alle Steuerzeichen, von #0 bis #$20 (aka #32).
|
AW: Problem mit procedure Split()
komischt, wenn ich ein string erzeuge zb.
Code:
dann wird #0 nicht mit Trim entfernt
'blabla' + #0
|
AW: Problem mit procedure Split()
Bei meinem Delphi schon.
Welche Delphi-Version hast du denn? |
AW: Problem mit procedure Split()
das weiß ich selber nicht genau welche delphi version das sein soll
ähnelt der version 5 |
AW: Problem mit procedure Split()
Zitat:
gruss |
AW: Problem mit procedure Split()
das ist nicht direkt delphi, das ist ein anderes Programm, benutzt aber die Delphi Sprache
|
AW: Problem mit procedure Split()
FreePascal (FPC) oder Lazarus?
Nja, in dem Fall hast du ja sowieso die Quellcodes zur Hand und könntest dir einfach mal ansehn wie Trim bei dir implementiert ist. Bei mir wird auf
Delphi-Quellcode:
verglichen und demnach alle unteren Steuerzeichen #0 bis #31 und das Leerzeichen (#32) entfernt.
<= ' '
|
AW: Problem mit procedure Split()
hmm, mache hier 200 zeilen code, und zum schluss:
Delphi-Quellcode:
danach klappt auch die Split Funktion
while pos(#0,s)>0 do begin
delete(s,pos(#0,s),1); end; ärgerlich, aber klappt super :) |
AW: Problem mit procedure Split()
Performance ist Dir egal, oder? Dein Code ist nämlich sehr langsam, da würde der Algorithmiker Pickel bekommen... ;-)
|
AW: Problem mit procedure Split()
Man könte auch mit StringReplace() versuchen
|
AW: Problem mit procedure Split()
hatte auch mit StringReplace() versucht, doch leider gibt es diese Funktion nicht :(
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:01 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