Autor Beitrag
Arbengie
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 66



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Sa 12.06.10 13:42 
Moin!

Wenig Aufwand: schau dir mal Suche in: Delphi-Forum, Delphi-Library TSTRINGLIST.COMMATEXT an. :idea: ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
ALF
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Sa 12.06.10 13:47 
user profile iconDude566 hat folgendes geschrieben Zum zitierten Posting springen:
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 :wink:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 66



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Sa 12.06.10 13:55 
Das ist ja was anderes, als das was in Deinem Anfang steht!
Ansonsten siehe user profile iconNarses

Gruss Alf

_________________
Wenn jeder alles kann oder wüsste und keiner hätt' ne Frage mehr, omg, währe dieses Forum leer!
Arbengie Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 66



BeitragVerfasst: Sa 12.06.10 14:03 
Ja, aber da sind keine Kommata, wie man sie für TStingList.CommaText brauch
Dude566
ontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic starofftopic star
Beiträge: 1592
Erhaltene Danke: 79

W8, W7 (Chrome, FF, IE)
Delphi XE2 Pro, Eclipse Juno, VS2012
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1085
Erhaltene Danke: 53

WinXP, Win7, Win10
Delphi 7 Enterprise, XE
BeitragVerfasst: Sa 12.06.10 14:17 
user profile iconArbengie hat folgendes geschrieben Zum zitierten Posting springen:
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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Sa 12.06.10 14:28 
Moin!

user profile iconArbengie hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 66



BeitragVerfasst: Sa 12.06.10 14:58 
Hab mal was versucht wie es in manchen Beispielen gemacht wird:

ausblenden 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 :P


Zuletzt bearbeitet von Arbengie am Sa 12.06.10 15:34, insgesamt 1-mal bearbeitet
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Sa 12.06.10 15:13 
Und wo wird die Stringliste wieder freigegeben? Wo ist der Ressourcenschuttzblock? Wo ist die Fehlerbehandlung?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
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)
BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 :mrgreen:):
ausblenden volle Höhe Delphi-Quelltext
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^ = #0then
    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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: Sa 12.06.10 18:49 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
(...) ganz schnell (...) hingezimmerter Versuch (...) hab grad kein Delphi zum Testen (...) Pointern

:bawling:

Arbengie, hast du Einfluss auf das Eingabeformat? Ich würde dir raten, ein Standardformat wie CSV zu verwenden. Felder mit zwei Leerzeichen zu trennen, weil die Felder selbst Leerzeichen haben klingt für mich nicht nach einem robusten Design. Falls du keinen Einfluss hast; im Internet solltest du eine geeignete Stringsplitter oder Explode Routine finden. Du bist bestimmt nicht der erste ;)
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19346
Erhaltene Danke: 1754

W11 x64 (Chrome, Edge)
Delphi 12 Pro, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: So 13.06.10 08:41 
So, ich habe es noch getestet, funktioniert natürlich auch. Hier noch eine zweite Variante:
ausblenden volle Höhe Delphi-Quelltext
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^ = #0then
    begin
      Count := Integer(CurPos) - Integer(CurValue);
      if NextPos^ = #0 then
        Inc(Count);
      case Index of
        0: TryStrToInt(Copy(CurValue, 1, Count), PInteger(CurData)^);
        12: 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:
ausblenden volle Höhe Delphi-Quelltext
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^ = #0then
    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.

user profile icondelfiphan hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
(...) ganz schnell (...) hingezimmerter Versuch (...) hab grad kein Delphi zum Testen (...) Pointern

:bawling:
Ich habe es mir schon gut genug überlegt was da passiert. ;-)
delfiphan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2684
Erhaltene Danke: 32



BeitragVerfasst: So 13.06.10 09:40 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
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.