![]() |
Strings laden
Und wieder einmal habe ich ein kleines Problem :(
Ich habe eine *.txt Datei in dieser stehen lange Texte drin. Hinter jedem Textende ist eine Markierung in diesem Beispiel "(!!)hier könnte noch unterschiedlicher Text stehen(!!)" danach kommt ein Zeilenumbruch und ein neuer Text fängt an. AAAAAAAAAA=BBBBBBBBBB=CCCCCCCCCC=DDDDDDDDDD=EEEEEE EEEE=FFFFFFFFFF=GGGGGGGGGG(!!)hier könnte noch unterschiedlicher Text stehen(!!) HHHHHHHHHH=IIIIIIIIII=JJJJJJJJJJ=KKKKKKKKKK=LLLLLL LLLL=MMMMMMMMMM=NNNNNNNNNN(!!)hier könnte noch unterschiedlicher Text stehen(!!) Ich möchte jetzt die *.txt Datei in eine ListBox laden was ja so kein Problem ist. Nur läd er immer jeden Textblock also immer bis zum nächsten Zeilenumbruch in einem String. Also in ListBox1.Items.Strings[0]steht dann der gesamte erste Text in ListBox1.Items.Strings[1] der gesamte 2. text und so weiter. Ich möchte aber gerne das der Inhalt der *.txt Datei so geladen wird
Delphi-Quellcode:
Ich hoffe ihr habt verstanden was ich überhaupt will :-D
// Darstellung in der Listbox
AAAAAAAAAA BBBBBBBBBB CCCCCCCCCC DDDDDDDDDD EEEEEEEEEE FFFFFFFFFF GGGGGGGGGG(!!)hier könnte noch unterschiedlicher Text stehen(!!) HHHHHHHHHH IIIIIIIIII JJJJJJJJJJ KKKKKKKKKK LLLLLLLLLL MMMMMMMMMM NNNNNNNNNN(!!)hier könnte noch unterschiedlicher Text stehen(!!) // und so weiter lg: Doris |
Re: Strings laden
gibt es nicht Listbox.items
(TStrings?!).delimiter? den einfach auf '=' setzen und dann laden. ansonsten mit einer stringlist, die hat ganz sicher einen delimiter. PS: hast du das nicht schon einmal gefragt? |
Re: Strings laden
Zitat:
Das einzige das mir dazu einfällt ist dieses
Delphi-Quellcode:
nicht getestet !
procedure TForm1.BitBtn1Click(Sender: TObject);
var i: Integer; sBox: String; slDat: TStringList; begin slDat.Create; for i := 0 to slDat.Count -1 do begin sBox := slDat.Strings[i]; while pos('=',sBox) <> 0 do begin slDat.Add(copy(sBox,1,pos('=',sBox)-1)); delete(sBox,1,pos('=',sBox)); end;//while ListBox1.Items.Add(sBox); end; //for end; // TForm1.BitBtn1Click |
Re: Strings laden
Hallo,
ich arbeite auch mit D5. Da es in D5 den Delimiter nicht gibt habe ich TStringList damit nachgerüstet.
Delphi-Quellcode:
unit JsStringListExt;
interface uses SysUtils, Windows, classes; Type TJsStringListExt = class(TStringList) private FDelimiter: Char; function GetCommaText: string; procedure SetCommaText(const Value: string); public constructor Create; property Delimiter : Char read FDelimiter write FDelimiter; property CommaText : string read GetCommaText write SetCommaText; end; implementation { TJsStringListExt } constructor TJsStringListExt.Create; begin inherited Create; FDelimiter:=','; end; function TJsStringListExt.GetCommaText: string; var S: string; P: PChar; I, Count: Integer; begin Count := GetCount; if (Count = 1) and (Get(0) = '') then Result := '""' else begin Result := ''; for I := 0 to Count - 1 do begin S := Get(I); P := PChar(S); while not (P^ in [#0..' ','"',FDelimiter]) do P := CharNext(P); if (P^ <> #0) then S := AnsiQuotedStr(S, '"'); Result := Result + S + ','; end; System.Delete(Result, Length(Result), 1); end; end; procedure TJsStringListExt.SetCommaText(const Value: string); var P, P1: PChar; S: string; begin BeginUpdate; try Clear; P := PChar(Value); while P^ in [#1..' '] do P := CharNext(P); while P^ <> #0 do begin if P^ = '"' then S := AnsiExtractQuotedStr(P, '"') else begin P1 := P; while (P^ > ' ') and (P^ <> FDelimiter) do P := CharNext(P); SetString(S, P1, P - P1); end; Add(S); while P^ in [#1..' '] do P := CharNext(P); if P^ = FDelimiter then repeat P := CharNext(P); until not (P^ in [#1..' ']); end; finally EndUpdate; end; end; end. |
Re: Strings laden
Jetzt ist es vorbei ich steig da nicht mehr durch bin vielleicht doch zu blond wenn auch nur gefärbt :-D
|
Re: Strings laden
Noch ein Ansatz:
Delphi-Quellcode:
Deine Zeilen musst du der Prozedur AddLines() übergeben:
function ParseStr(var s: string; delimiters: string; purge: boolean): string;
var i: integer; begin i := 0; while (i < Length(s)) and (Pos(s[Succ(i)], delimiters) = 0) do Inc(i); Result := Copy(s, 1, i); Delete(s, 1, i + Ord(purge)); end; procedure AddLines(s: TStrings; line: string; delimiter: char); begin while line <> '' do s.Add(ParseStr(line, delimiter, true)); end;
Delphi-Quellcode:
Das Trennzeichen darf im hinten angehängten Text allerdings nicht vorkommen.
AddLines(ListBox.Items, DeineZeilenVariable, '=');
Grüße vom marabu |
Re: Strings laden
Marabu mit deinem Beispiel geht es sehr gut mit
Delphi-Quellcode:
wird nun alles in die ListBox1 geladen felht nur noch der Zeilenumbruch also ListBox1.Items.Add(#13#10) nach jedem Textblock wie unten zu sehen
AddLines(ListBox1.Items, sDat, '=');
// Darstellung in der Listbox AAAAAAAAAA BBBBBBBBBB CCCCCCCCCC DDDDDDDDDD EEEEEEEEEE FFFFFFFFFF GGGGGGGGGG(!!)hier könnte noch unterschiedlicher Text stehen(!!) Zeilenumbruch HHHHHHHHHH IIIIIIIIII JJJJJJJJJJ KKKKKKKKKK LLLLLLLLLL MMMMMMMMMM NNNNNNNNNN(!!)hier könnte noch unterschiedlicher Text stehen(!!) Zeilenumbruch ein großen DANK nochmal an alle lg: Doris |
Re: Strings laden
Eine Leerzeile fügst du so in eine ListBox ein:
Delphi-Quellcode:
marabu
ListBox.Lines.Add('');
|
Re: Strings laden
Zitat:
Eine Leerzeile möchte ich nicht einfügen sondern ein Zeilenumbruch
Delphi-Quellcode:
// jetzige Darstellung in der Listbox mit deinem Beispiel
AAAAAAAAAA BBBBBBBBBB CCCCCCCCCC DDDDDDDDDD EEEEEEEEEE FFFFFFFFFF GGGGGGGGGG(!!)hier könnte noch unterschiedlicher Text stehen(!!) HHHHHHHHHH IIIIIIIIII JJJJJJJJJJ KKKKKKKKKK LLLLLLLLLL MMMMMMMMMM NNNNNNNNNN(!!)hier könnte noch unterschiedlicher Text stehen(!!)
Delphi-Quellcode:
// künftige Darstellung in der Listbox
AAAAAAAAAA BBBBBBBBBB CCCCCCCCCC DDDDDDDDDD EEEEEEEEEE FFFFFFFFFF GGGGGGGGGG(!!)hier könnte noch unterschiedlicher Text stehen(!!) //hier soll ein Zeilenumbruch immer nach Textende hin also Add(#13#10) HHHHHHHHHH IIIIIIIIII JJJJJJJJJJ KKKKKKKKKK LLLLLLLLLL MMMMMMMMMM NNNNNNNNNN(!!)hier könnte noch unterschiedlicher Text stehen(!!) //hier soll ein Zeilenumbruch immer nach Textende hin also Add(#13#10) lg: Doris |
Re: Strings laden
Hallo Doris,
wenn du ein Programm entwickelst, dann achte immer auf eine saubere Trennung von Form und Funktion. Implementiere zuerst die Funktion und überlege dir dann eine angemessene Form der Darstellung. Du hast zwar keine Hintergrundinformationen zu deinem Problem gegeben, aber es lässt sich auch so gut als eine string transformation erkennen. Die Funktion unter Verwendung von TStrings zu implementieren ist da eine gute Entscheidung. In meinem Beitrag #6 wirst du auch bei intensiver Suche keine Hinweise auf visuelle Komponenten entdecken. Ich habe ja auch nur die gesuchte Funktionalität implementiert. Bei der Visualisierung ist die ListBox eher eine schlechte Wahl, weil gleich mehrere best practices missachtet werden. Zum einen ist die ListBox in erster Linie ein Selektions-Instrument. Die gängigen style guides empfehlen eine sichtbare Anzahl von etwa sieben items - unser Gehirn empfindet diese Informationsdichte als angenehm. Die items müssen semantisch homogen sein - deine sind es nicht (es gibt Indizien dafür). Die Gesamtzahl der items in einer Listbox sollte nicht zu groß sein, aber die Grenzen hängen dabei stark vom implementierten Bedienkomfort ab. Es gibt auch keinen Gestaltungsspielraum bei den items, insbesondere keine Leer-Items. Das folgt direkt aus der Homogenitätsbedingung. Einen Zeilenumbruch gibt es in einem Fließtext, aber nicht in einer Auswahlliste. Technisch gesehen ist ein Zeilenumbruch in einer StringListe eine Leerzeile und wird mit Strings.Add('') erzeugt. Das Hinzufügen mit Strings.Add(#13#10) erzeugt zwei Leerzeilen, da die StringList #13#10 grundsätzlich als Zeilentrenner verwendet. Das kannst du sehr leicht sehen, wenn du eine leere ListBox und einen Button auf eine TestForm ziehst und im OnClick-Ereignis des Button folgendes machst:
Delphi-Quellcode:
Durch das Einfügen eines Zeilenumbrüche enthaltenden Strings mit Add() wird der interne Parser der TStrings-Komponente umgangen. Da die Steuerzeichen #13 und #10 innerhalb eines Strings weder Bedeutung noch einen Graph besitzen, wird der Graph für nicht darstellbare Zeichen ausgegeben. Wenn du die Kommentarzeichen entfernst, dann wird durch erneutes Parsen des Textes jeder Zeilenumbruch erkannt und korrekt umgesetzt.
procedure TTestForm.ButtonClick(Sender: TObject);
begin with ListBox.Items do begin Clear; Add('make'#13#10'my'#13#10'day'); // Text := Text; end; end; Die Zeilenumbrüche haben für die StringList eine interne Bedeutung. Wenn du sie unter Umgehung des Parsers hinzufügst, dann sorgst du vorübergehend für eine Inkosistenz in der Darstellung, aber an der Funktionalität änderst du nichts. Mache es also lieber gleich richtig. Und denke einmal darüber nach, ob eine mehrspaltige Darstellung deiner Daten nicht angemessener wäre. Wenn du aber doch an einer vertikalen Ausgabe festhalten willst, dann ist wohl die Memo-Komponente besser als die ListBox geeignet. Freundliche Grüße vom marabu |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:47 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