Autor Beitrag
Martello
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 131

WIN 2000
TP, C, Delphi 1.0, Turbo Delphi 2006, Delphi 7
BeitragVerfasst: Fr 11.06.10 23:25 
Eine einfache Frage - nur nicht für mich: :?

Wie kann ich in Delphi elegant mit readln(text, ..,..,...,.) kommaseparierte Substrings beim Einlesen "erfassen" und die Elemente anschließend typkonvertieren und in ein entsprechendes Record einfügen? Die Substrings können von Zeile zu Zeile in ihrer Länge variieren.

Danke für Hilfe,
M.
Xentar
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 2077
Erhaltene Danke: 2

Win XP
Delphi 5 Ent., Delphi 2007 Prof
BeitragVerfasst: Fr 11.06.10 23:55 
Wenn die wirklich getrennt sind, könntest du TStringList.DelimitedText bzw. TStringList.Commatext verwenden

_________________
PROGRAMMER: A device for converting coffee into software.
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: Fr 11.06.10 23:56 
Und effizient würde ich das ganze zeichenweise durchgehen und jeweils in den entsprechenden Teil des Records kopieren.

Wenn man das mit PChar macht, geht das seht schnell.
Martello Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 131

WIN 2000
TP, C, Delphi 1.0, Turbo Delphi 2006, Delphi 7
BeitragVerfasst: Sa 12.06.10 13:00 
user profile iconXentar hat folgendes geschrieben Zum zitierten Posting springen:
Wenn die wirklich getrennt sind, könntest du TStringList.DelimitedText bzw. TStringList.Commatext verwenden


Wirklich getrennt werden die durch Kommata; am Anfang sogar noch mit Excel erzeugt und gespeichert via *.csv :oops:

Mit TStringList habe ich bereits ein wenig Erfahrung; allerdings hatte ich es seiner Zeit nur verwendet, um eine erzeugte
Matrix zu buffern, um sie schließlich als *.txt exportieren zu können. Explizit habe ich also "Delimiter" noch nicht angewendet.

Mit TStingList lese ich doch die ganze Datei auf einmal; und anschließend würde ich Zeile für Zeile separieren. Irgendwie so ähnlich - dachte ich - müsste es wohl gehen. :? Und da die Substringlänge einer Spalte manchmal von Zeile zu Zeile variiert, dürfte das mit TStringList.Delimited.Text bzw. ..Commatext wohl die einfachere Methode sein im Vergleich zu jaenickes Emfehlung pro PChar. (Es sei denn, man hat bereits viel Routine im Umgang mit Pointern :wink: )

Ich bin gespannt, danke für die Tipps.
M.
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:06 
Wenn die aus Excel kommen, würde ich eher dazu raten die Datei auch als Exceldatei zu speichern. Denn dann muss man nicht erst lange parsen.

Was die Pointer angeht:
So schwer und viel Quelltext ist das nicht. Siehe hier, da lese ich zeichenweise aus einem Speicherbereich:
www.delphi-forum.de/viewtopic.php?t=99933

Das grundsätzliche Vorgehen ist, dass man einen PChar auf das erste Zeichen des Strings hat. Dann inkrementiert man diesen Pointer jeweils und hat dann (da ein Pointer nullterminiert ist) immer den Rest des Strings drin. Aber das alles ohne den String an sich ändern zu müssen.
Dadurch geht das ganze sehr viel schneller. Ich suche das Endzeichen und kopiere dann die Zeichen zwischen dem aktuellen Anfang und dem Zeichen in den Record. Dann setze ich den Anfang auf das folgende Zeichen. Und so weiter. ;-)

Die Frage ist auch wie schnell das sein muss usw., denn Optimierung ist zwar schön (und macht mir auch Spaß), aber man muss eben immer Lesbarkeit und Wartbarkeit des Codes gegen die an der Stelle wirklich notwendige Geschwindigkeit abwägen.
Martello Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 131

WIN 2000
TP, C, Delphi 1.0, Turbo Delphi 2006, Delphi 7
BeitragVerfasst: Sa 12.06.10 18:38 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
Wenn die aus Excel kommen, würde ich eher dazu raten die Datei auch als Exceldatei zu speichern. Denn dann muss man nicht erst lange parsen.


Ich möchte mich nicht auf das *.xls-Format festlegen; später soll es kommaseparierter *.txt sein, egal wie die Endungen dann lauten. Das mit PChar muss auch noch warten. Erst mal hab ich den Umgang mit TStringList zu üben: :oops:

ausblenden Delphi-Quelltext
1:
2:
3:
var
   sl, slRow : TStringList;
   line, col : integer;

Aus dem vorstehenden Delphi-Text lerne ich, dass man auch einzelne Strings/Zeilen ("slRow") als TSringList verwenden kann/sollte, um zu...



ausblenden Delphi-Quelltext
1:
2:
3:
    //"load" the line into a stringlist
    slRow.DelimitedText := sl[line];
    StringGrid1.Rows[line].Assign(slRow);


Diese Zeilen habe ich aus einem Beispiel, das in ein StringGrid einliest. Das geht mit ...Assign(slRow) ja sehr elegant.
Um meine Substrings in ein Record "einzusokonvertieren" werde ich also auch so etwas wie
slRow.DelimitedText := sl[line] verwenden. Wie picke ich aber danach am einfachsten alle einzelnen Elemente aus meiner Zeile heraus? Gibt es hierfür Indizes oder Items oder ähnliches?

M.
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 19:33 
user profile iconMartello hat folgendes geschrieben Zum zitierten Posting springen:
Wie picke ich aber danach am einfachsten alle einzelnen Elemente aus meiner Zeile heraus? Gibt es hierfür Indizes oder Items oder ähnliches?
ausblenden Delphi-Quelltext
1:
2:
3:
slRow[0]
slRow[1]
...
;-)
Martello Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 131

WIN 2000
TP, C, Delphi 1.0, Turbo Delphi 2006, Delphi 7
BeitragVerfasst: Sa 12.06.10 20:33 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
ausblenden Delphi-Quelltext
1:
2:
3:
slRow[0]
slRow[1]
...
;-)


Ich hatte in der Zwischenzeit einmal in der Hilfe nachgelesen, und bin ein wenig erschrocken, dass es so einfach ist... :?

In TurboPascal verwende ich delay(ms), um Prozesse zu verlangsamen. Irgendwo las ich, in Delphi gäb's dafür sleep(ms)
(ein Tutorial über Timer in Delphi habe ich immerhin auch schon gefunden).

Aber bei "Sleep(ms)" innerhalb einer Schleife einer TForm1.Button1Click(Sender: TObject);
wacht er nicht mehr auf, da scheint irgendwas zu hängen, oder woran sonst könnte das liegen?

Gibt es einee einfachen Ersatz für mein delay() in Delphi?

M.
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 20:39 
Es gibt da zwar durchaus etwas:
www.delphipraxis.net...delay+revisited.html

Aber meistens sind solche Fragen Symptome eines schlechten / nicht durchdachten Konzepts... Meistens gibt es eine deutlich bessere Lösung.
Martello Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 131

WIN 2000
TP, C, Delphi 1.0, Turbo Delphi 2006, Delphi 7
BeitragVerfasst: Di 15.06.10 23:32 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:

Aber meistens sind solche Fragen Symptome eines schlechten / nicht durchdachten Konzepts... Meistens gibt es eine deutlich bessere Lösung.


Mit Delay() wollte ich den Prozess eigentlich nur verlangsamen, um ihm dabei zusehen zu können, wie er alle 256*256 Keys meines Array in ein Edit schreibt. Ohne Delay() sehe ich nur den letzten Wert. Und soll ich ihm jetzt trauen, dass er alle anderen zuvor auch korrekt geschrieben hat? :wink:

Aber Spaß beiseite:

Ich möchte ja 4 mal in der Sekunde GPS-Daten aus einem UBLOX via RS232 einlesen. Diese Strings kommen schön regelmäßig, und damit habe ich auch gleich einen exakten Taktgeber für mein Progrämmchen, von dem ich leider nicht weiß, ob ich es je zum Laufen kriege... :(

Insofern darf die Lektüre diverser "Timingkonzepte in Delphi" ruhig noch ein wenig liegen bleiben. Ich habe Cport erfolgreich installiert; nun studiere ich erst mal die mitgelieferte Hilfe. Weißt Du rein zufällig von ein paar passenden Delphi-Zeilen, die an einem Comport lauschen und regelmäßig Stringsendungen unbekannter Länge (die Längen der $GPRMC-Strings variieren leider) nach Delphi transportieren?

M.
Narses
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Administrator
Beiträge: 10185
Erhaltene Danke: 1261

W11x64
TP3 .. D7pro .. D10.2CE
BeitragVerfasst: Di 15.06.10 23:35 
Moin!

Bitte erstelle für jede deiner Fragen ein separates Topic, da die Diskussion mehrerer Fragen in einem Topic für gewöhnlich für Verwirrung und Durcheinander sorgt. Danke. ;)

cu
Narses

_________________
There are 10 types of people - those who understand binary and those who don´t.
Dieses Thema ist gesperrt, Du kannst keine Beiträge editieren oder beantworten.

Das Thema wurde von einem Team-Mitglied geschlossen. Wenn du mit der Schließung des Themas nicht einverstanden bist, kontaktiere bitte das Team.