| Autor |
Beitrag |
Arbengie
      
Beiträge: 66
|
Verfasst: Sa 12.06.10 13:35
Hi ich veruche grad nen Programm zu schreiben, bei dem man in ein Edit einen String mit mehreren Werten rein einfügt (z.B. "WertA WertB WertC"). Diese sind alle durch eine Leerzeichen getrennt. Und in drei anderen Edit Felder sollen diese Werte dann alleine angezeigt werden.
Da habe ich bisher mit Copy, Pos gearbeitet, nur das Problem ist, dass es ja mehrere Leerzeichen gibt und Pos nur das Erste immer anerkennt...
Wie komm ich da weiter bzw. gibts da auch en ganz andere elegantere Möglichkeit?
|
|
Dude566
      
Beiträge: 1592
Erhaltene Danke: 79
W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
|
Verfasst: Sa 12.06.10 13:38
Du könntest dein Konzept überlegen und vielleicht was sinnvolleres verwenden.
Du könntest aber auch nachdem du den 1. Wert herauskopiert hast diesen aus dem String löschen und dann den Rest weiterverarbeiten, wie ein Parser das auch macht.
_________________ Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Sa 12.06.10 13:42
Moin!
Wenig Aufwand: schau dir mal TSTRINGLIST.COMMATEXT an.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
ALF
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Sa 12.06.10 13:47
Dude566 hat folgendes geschrieben : | | Du könntest dein Konzept überlegen und vielleicht was sinnvolleres verwenden. |
Dem schliesse ich mich an. Da Du hier von Werte schreibst, gehe ich davon aus das es Zahlenwerte sind.
Warum also so kompliziert machen wenn man gleich 3 Editfelder dafür nehmen kann
Zumal Du dies ja in 3 Editfelder übertragen tust.
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
Arbengie 
      
Beiträge: 66
|
Verfasst: Sa 12.06.10 13:52
Also man kopiert ne Zeile aus dem Internet und fügt die dort ein und das Programm soll das dann halt "zerteilen"
Das was man reinkopiert is konkret:
"24 Red County Timo87 0 % 17 L 1104 km/2054 km"
Ich brauche daraus für Editfeld einen Wert(für das Bsp.):
-24
-Red County
-Timo87
-0
-17
-1104
Zuletzt bearbeitet von Arbengie am Sa 12.06.10 14:02, insgesamt 1-mal bearbeitet
|
|
ALF
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Sa 12.06.10 13:55
Das ist ja was anderes, als das was in Deinem Anfang steht!
Ansonsten siehe Narses
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
Arbengie 
      
Beiträge: 66
|
Verfasst: Sa 12.06.10 14:03
Ja, aber da sind keine Kommata, wie man sie für TStingList.CommaText brauch
|
|
Dude566
      
Beiträge: 1592
Erhaltene Danke: 79
W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
|
Verfasst: Sa 12.06.10 14:06
Schreibe den Text aus dem Edit in eine Variable vom Typ String und zerlege dann diesen nach deinen Wünschen mit Pos etc in weitere Variablen, die du dann in deinen Edits einfügen kannst.
_________________ Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.
|
|
ALF
      
Beiträge: 1085
Erhaltene Danke: 53
WinXP, Win7, Win10
Delphi 7 Enterprise, XE
|
Verfasst: Sa 12.06.10 14:17
Arbengie hat folgendes geschrieben : | | Ja, aber da sind keine Kommata, wie man sie für TStingList.CommaText brauch |
Dann solltest Du Dir mal die Hilfe durchlesen
TStingList.Delimiter := Char, kann also (',') (' ') ('#') (':') sein usw.
Gruss Alf
_________________ Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
|
|
Narses
      

Beiträge: 10185
Erhaltene Danke: 1261
W11x64
TP3 .. D7pro .. D10.2CE
|
Verfasst: Sa 12.06.10 14:28
Moin!
Arbengie hat folgendes geschrieben : | | Ja, aber da sind keine Kommata, wie man sie für TStingList.CommaText brauch |
Das ist auch nicht unbedingt wichtig, WhiteSpace zählt wie Komma. Einfach mal ausprobieren.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Arbengie 
      
Beiträge: 66
|
Verfasst: Sa 12.06.10 14:58
Hab mal was versucht wie es in manchen Beispielen gemacht wird:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| Input.Text := '24 Red County Timo87 0 % 17 L 1104 km/2054 km';
procedure TForm1.Button1Click(Sender: TObject); var input: TStringList; s1: string; begin input := TStringList.Create; input.CommaText := edtinput.Text; s1 := input.Values['24']; Edtoutput.Text := s1; end; |
Fehler: Nix passiert 
Zuletzt bearbeitet von Arbengie am Sa 12.06.10 15:34, insgesamt 1-mal bearbeitet
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Sa 12.06.10 15:13
Und wo wird die Stringliste wieder freigegeben? Wo ist der Ressourcenschuttzblock? Wo ist die Fehlerbehandlung?
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 12.06.10 15:17
Values bringt dir hier wenig, da du keine Zeilen wie "24=Mein Wert" hast. Du brauchst input[0], input[1], ...
Wobei hier ein manuelles Vorgehen sinnvoller wäre. Denn automatisch bekommt man das doppelte Leerzeichen nicht als Trennzeichen hin.
|
|
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: Sa 12.06.10 16:01
Hey,
ich Werf mal PosEx in den Raum...
MfG Bergmann
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Sa 12.06.10 17:08
Mal nen ganz schnell hingezimmerter Versuch, sollte klappen, hab grad kein Delphi zum Testen da (jetzt erst Recht mit Pointern  ): 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43:
| type TExampleData = record Age, Group, Name, Progress, L, Position: string; procedure LoadFromString(const Value: string); end;
procedure TExampleData.LoadFromString(const Value: string); var CurPos, CurValue, NextPos: PChar; CurData: PString; Count: Integer; begin CurPos := @Value[1]; CurValue := CurPos; CurData := @Age; while CurPos^ <> #0 do begin NextPos := PChar(Integer(CurPos) + SizeOf(Char)); if ((CurPos^ = ' ') and (NextPos^ = ' ')) or (NextPos^ = #0) then begin Count := Integer(CurPos) - Integer(CurValue); if NextPos^ = #0 then Inc(Count); CurData^ := Copy(CurValue, 1, Count); Inc(CurData); Inc(CurPos); CurValue := CurPos; Inc(CurValue); end; Inc(CurPos); end; end;
var ExampleRecord: TExampleData; begin ExampleRecord.LoadFromString(edtInput.Text); memResult.Lines.Add(ExampleRecord.Age); memResult.Lines.Add(ExampleRecord.Group); memResult.Lines.Add(ExampleRecord.Name); memResult.Lines.Add(ExampleRecord.Progress); memResult.Lines.Add(ExampleRecord.L); memResult.Lines.Add(ExampleRecord.Position); | Sollte ab Delphi 2006 / Turbo Delphi so gehen.
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: Sa 12.06.10 18:49
|
|
jaenicke
      
Beiträge: 19346
Erhaltene Danke: 1754
W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: So 13.06.10 08:41
So, ich habe es noch getestet, funktioniert natürlich auch. Hier noch eine zweite Variante: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46:
| type TExampleData = record Age: Integer; Group, Name: string; Progress, L, Position: Integer; procedure LoadFromString(const Value: string); procedure LoadFromString2(const Value: string); end;
procedure TExampleData.LoadFromString(const Value: string); var CurPos, CurValue, NextPos, BlankPos: PChar; CurData: Pointer; Count, Index: Integer; begin CurPos := @Value[1]; CurValue := CurPos; CurData := @Age; Index := 0; BlankPos := nil; while CurPos^ <> #0 do begin if (CurPos^ = ' ') and not Assigned(BlankPos) then BlankPos := CurPos; NextPos := PChar(Integer(CurPos) + SizeOf(Char)); if ((CurPos^ = ' ') and (NextPos^ = ' ')) or (NextPos^ = #0) then begin Count := Integer(CurPos) - Integer(CurValue); if NextPos^ = #0 then Inc(Count); case Index of 0: TryStrToInt(Copy(CurValue, 1, Count), PInteger(CurData)^); 1, 2: PString(CurData)^ := Copy(CurValue, 1, Count); 3..5: TryStrToInt(Copy(CurValue, 1, Integer(BlankPos) - Integer(CurValue)), PInteger(CurData)^); end; Inc(PLongWord(CurData)); Inc(CurPos); CurValue := CurPos; Inc(CurValue); Inc(Index); BlankPos := nil; end; Inc(CurPos); end; end; | Und ohne Pointerspielerei die "normale" Version für den Recordzugriff: 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36:
| procedure TExampleData.LoadFromString(const Value: string); var CurPos, CurValue, NextPos, BlankPos: PChar; Count, Index: Integer; begin CurPos := @Value[1]; CurValue := CurPos; Index := 0; BlankPos := nil; while CurPos^ <> #0 do begin if (CurPos^ = ' ') and not Assigned(BlankPos) then BlankPos := CurPos; NextPos := PChar(Integer(CurPos) + SizeOf(Char)); if ((CurPos^ = ' ') and (NextPos^ = ' ')) or (NextPos^ = #0) then begin Count := Integer(CurPos) - Integer(CurValue); if NextPos^ = #0 then Inc(Count); case Index of 0: TryStrToInt(Copy(CurValue, 1, Count), Age); 1: Group := Copy(CurValue, 1, Count); 2: Name := Copy(CurValue, 1, Count); 3: TryStrToInt(Copy(CurValue, 1, Integer(BlankPos) - Integer(CurValue)), Progress); 4: TryStrToInt(Copy(CurValue, 1, Integer(BlankPos) - Integer(CurValue)), L); 5: TryStrToInt(Copy(CurValue, 1, Integer(BlankPos) - Integer(CurValue)), Position); end; Inc(CurPos); CurValue := CurPos; Inc(CurValue); Inc(Index); BlankPos := nil; end; Inc(CurPos); end; end; | Wichtig: Fehlerbehandlung fehlt in beiden noch, denn Umwandlungsfehler werden zwar abgefangen, aber nicht behandelt.
delfiphan hat folgendes geschrieben : | jaenicke hat folgendes geschrieben : | | (...) ganz schnell (...) hingezimmerter Versuch (...) hab grad kein Delphi zum Testen (...) Pointern |
|
Ich habe es mir schon gut genug überlegt was da passiert. 
|
|
delfiphan
      
Beiträge: 2684
Erhaltene Danke: 32
|
Verfasst: So 13.06.10 09:40
jaenicke hat folgendes geschrieben : | | Wichtig: Fehlerbehandlung fehlt in beiden noch, denn Umwandlungsfehler werden zwar abgefangen, aber nicht behandelt. |
Der Code gefällt mir auch aus einigen anderen Gründen nicht. Es fehlt die Validierung des Inputs; habe ich Range Checking eingeschaltet, geht's bei einem leeren String schief; ist Overflow Checking eingeschaltet, geht deine Integer Arithmetik bei Pointern vielleicht schief, wenn mit PEFlags $20 kompiliert. Ganz nebenbei sollte das Umwandeln von Pointer zu Integer tabu sein (wenn schon dann Cardinal oder UINT_PTR). Ungeachtet von Range Checking kann ich mit dem Code leicht Memory überschreiben, indem ich zu viele Werte übergebe. Dein Code ist stark platformabhängig und macht Annahmen über die interne Struktur von Strings. Kein Separation of Concern vorhanden, deine Funktion macht alles gleichzeitig und ist daher recht unübersichtlich und nicht wiederverwendbar (bei zwei ähnlichen Funktionen müsstest du das ganze mehr oder weniger 1:1 kopieren und modifizieren; wenn du einen Bug findest musst du es an zwei Orten fixen; wenn man "zwei Leerzeichen" durch "Tab" ersetzt, musst ggf. alles neu überlegen und umschreiben). Ich finde es übrigens besser, Fehler als solche zu schmeissen, statt stillschweigend mit TryStrToInt zu ignorieren.
|
|
|