Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Strings laden (https://www.delphipraxis.net/58930-strings-laden.html)

dorisdoloris 14. Dez 2005 17:54


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:
// 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
Ich hoffe ihr habt verstanden was ich überhaupt will :-D

lg: Doris

DGL-luke 14. Dez 2005 18:04

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?

dorisdoloris 14. Dez 2005 18:32

Re: Strings laden
 
Zitat:

Zitat von DGL-luke
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?

Delimiter gibt es bei mir nicht ich benutze Delphi 5.0

Das einzige das mir dazu einfällt ist dieses

Delphi-Quellcode:
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
nicht getestet !

Jens Schumann 14. Dez 2005 18:42

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.

dorisdoloris 14. Dez 2005 18:48

Re: Strings laden
 
Jetzt ist es vorbei ich steig da nicht mehr durch bin vielleicht doch zu blond wenn auch nur gefärbt :-D

marabu 14. Dez 2005 19:37

Re: Strings laden
 
Noch ein Ansatz:

Delphi-Quellcode:
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;
Deine Zeilen musst du der Prozedur AddLines() übergeben:

Delphi-Quellcode:
AddLines(ListBox.Items, DeineZeilenVariable, '=');
Das Trennzeichen darf im hinten angehängten Text allerdings nicht vorkommen.

Grüße vom marabu

dorisdoloris 14. Dez 2005 20:26

Re: Strings laden
 
Marabu mit deinem Beispiel geht es sehr gut mit

Delphi-Quellcode:
AddLines(ListBox1.Items, sDat, '=');
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


// 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

marabu 14. Dez 2005 20:54

Re: Strings laden
 
Eine Leerzeile fügst du so in eine ListBox ein:

Delphi-Quellcode:
ListBox.Lines.Add('');
marabu

dorisdoloris 15. Dez 2005 05:02

Re: Strings laden
 
Zitat:

Zitat von marabu
Eine Leerzeile fügst du so in eine ListBox ein:

Delphi-Quellcode:
ListBox.Lines.Add('');
marabu

Guten Morgen Marabu

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

marabu 15. Dez 2005 06:42

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:
procedure TTestForm.ButtonClick(Sender: TObject);
begin
  with ListBox.Items do
  begin
    Clear;
    Add('make'#13#10'my'#13#10'day');
    // Text := Text;
  end;
end;
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.

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 14:57 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz