Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi TStringList, Pos, PosEx usw.311 (https://www.delphipraxis.net/160932-tstringlist-pos-posex-usw-311-a.html)

PredatorMask 8. Jun 2011 12:20

Delphi-Version: 7

TStringList, Pos, PosEx usw.311
 
hey liebe community,

ich bin grad dabei, ein sehr simples programm zu entwickeln, was mir aber mehr kopfzerbrechen bereitet, als ich dachte. ich denke, dass ich es einfach mit dem ablauf nicht hinkriege...

ich möchte eine datei auslesen (1.txt) in der folgendermaßen aufgeteilt wird:

Code:
hallo eins:
blabla
blabla
blabla
hallo zwei:
blabla
blabla
blabla
hallo eins:
blabla
...
...
nun möchte ich alles, was zwischen (einschließlich) "hallo eins" bis (ausschließlich) "hallo zwei" steht, in RichEdit1 hinzufügen und das gleiche mit (einschließlich) "hallo zwei" bis (ausschließlich) "hallo eins" nur in RichEdit2.

heisst also, alles was hallo eins zu sagen hat in richedit1 rein und alles, was hallo zwei zu sagen hat in richedit2 rein :thumb:

so, jetzt bitte nicht lachen, wenn ihr meinen bisherigen CODErwelsch seht, denn ich bin leider nicht so der logiker ...

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
load: tstringlist;
counter, i1, i2: integer;
begin
load := tstringlist.create;
load.loadfromfile('C:\1.txt');
counter := 0;
i1      := pos('hallo eins',load.text);
i2      := pos('hallo zwei',load.text);
for counter := 0 to load.Count do
  begin
    richedit1.Lines.Add(copy(load.text,i1,i2-1));
    i1 := posex('hallo eins',load.text,i2+1);
    i2 := posex('hallo zwei',load.text,i2+1);
  end;
end;
ich weiss, es ist wahrscheinlich total falsch, aber ich hab, statt gleich einen neuen thread zu eröffnen, bis gestern nacht um 4 uhr gesucht und rumprobiert, nur es will einfach nicht funktionieren :cry:

ich wäre sehr dankbar über jede hilfe :thumb: und habt etwas verständnis für einen newbie :stupid:

viele liebe grüße

DeddyH 8. Jun 2011 12:33

AW: TStringList, Pos, PosEx usw.311
 
Hallo und Willkommen in der DP :dp:,

versuch es einmal so (ungetestet):
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  load: tstringlist;
  Counter: integer;
begin
  load := tstringlist.create;
  try
    load.loadfromfile('C:\1.txt');
    counter := 0;
    //zunächst die Anfangszeile suchen
    while (counter < load.Count) and not StrUtils.AnsiSameText('hallo eins:', load[counter]) do
      inc(counter);
    //alle folgenden Zeilen bis zur "Ende"-Zeile ins erste RichEdit kopieren
    while (counter < load.Count) and not StrUtils.AnsiSameText('hallo zwei:', load[counter]) do
      begin
        RichEdit1.Lines.Add(load[Counter]);
        inc(Counter);
      end;
    //alle folgenden Zeilen bis zur "Ende"-Zeile ins zweite RichEdit kopieren
    while (counter < load.Count) and not StrUtils.AnsiSameText('hallo eins:', load[counter]) do
      begin
        RichEdit2.Lines.Add(load[Counter]);
        inc(Counter);
      end;
  finally
    load.Free;
  end;
end;
Falls ich keine allzugroßen Denkfehler gemacht habe, sollte das im Wesentlichen so funktionieren.

[edit] *Oops* ich hatte gar nicht auf das Anmeldedatum geachtet. Naja, eine freundliche Begrüßung kann ja nie schaden :lol: [/edit]

PredatorMask 8. Jun 2011 12:37

AW: TStringList, Pos, PosEx usw.311
 
hey!

danke für die schnelle antwort.

zumal ich ein paar sachen nicht verstehe, mit denen ich dich aber nicht nerven will und mir im internet mal näheres dazu anschaue, funktioniert folgendes nicht:

er meint, StrUtils.AnsiSameText() wär ein undeclared identifier :|

mkinzler 8. Jun 2011 12:39

AW: TStringList, Pos, PosEx usw.311
 
Hast du die Unit eingebunden?

PredatorMask 8. Jun 2011 12:40

AW: TStringList, Pos, PosEx usw.311
 
Zitat:

Zitat von mkinzler (Beitrag 1105248)
Hast du die Unit eingebunden?

jep, deswegen wunderts mich auch :thumb:

//edit: ja bin schon etwas länger in der community, nur zwischenzeitlich keine zeit gefunden zum programmieren :)

DeddyH 8. Jun 2011 12:50

AW: TStringList, Pos, PosEx usw.311
 
Oh, sry, die Funktion scheint aus SysUtils zu stammen. Ob das unter Delphi 7 auch so ist musst Du selbst probieren.

Aphton 8. Jun 2011 13:00

AW: TStringList, Pos, PosEx usw.311
 
Delphi-Quellcode:
//Fehler
  richedit1.Lines.Add(copy(load.text,i1,i2-1));
Ich glauber hier liegt der Fehler. Copy(Str, Von, Stellen) kopiert vom "Str" ab der Position "Von", "Stellen" Zeichen.

Copy('ABCD', 1, 2) = AB
Copy('ABCD', 2, 2) = BC
Copy('ABCD', 3, 2) = CD

Dein Fehler ist nun, dass du i2-1 nimmst. Es muss aber heißen i2-i1

PredatorMask 8. Jun 2011 13:27

AW: TStringList, Pos, PosEx usw.311
 
@DeddyH: Trotz Sysutils.AnsiSameText tut sich leider nichts :(

@Aphton: Ja, das sieht jetzt schon a way better aus :) nur das problem ist, dass trotzdem noch "hallo zwei" abschnitte in RichEdit1 mit hineinrutschen. wie kann ich das verhindern?

//edit: und für jede zeile, in der er nichts findet, fügt er #13 hinzu, also einen absatz eben. wie kann ich auch das verhindern? :D

DeddyH 8. Jun 2011 13:40

AW: TStringList, Pos, PosEx usw.311
 
Dann eben so:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

  function IsSameText(const str1, str2: string): Boolean;
  begin
    Result := AnsiStrIComp(PChar(str1), PChar(Str2)) = 0;
  end;

var
  load: tstringlist;
  Counter: integer;
begin
  load := tstringlist.create;
  try
    load.loadfromfile('C:\1.txt');
    counter := 0;
    //zunächst die Anfangszeile suchen
    while (counter < load.Count) and not IsSameText('hallo eins:', load[counter]) do
      inc(counter);
    //alle folgenden Zeilen bis zur "Ende"-Zeile ins erste RichEdit kopieren
    while (counter < load.Count) and not IsSameText('hallo zwei:', load[counter]) do
      begin
        RichEdit1.Lines.Add(load[Counter]);
        inc(Counter);
      end;
    //alle folgenden Zeilen bis zur "Ende"-Zeile ins zweite RichEdit kopieren
    while (counter < load.Count) and not IsSameText('hallo eins:', load[counter]) do
      begin
        RichEdit2.Lines.Add(load[Counter]);
        inc(Counter);
      end;
  finally
    load.Free;
  end;
end;

Aphton 8. Jun 2011 13:41

AW: TStringList, Pos, PosEx usw.311
 
Ja weil du beides "einschließlich" hinzufügst:
Zitat:

nun möchte ich alles, was zwischen (einschließlich) "hallo eins" bis (ausschließlich) "hallo zwei" steht, in RichEdit1 hinzufügen und das gleiche mit (einschließlich) "hallo zwei" bis (ausschließlich) "hallo eins" nur in RichEdit2.
Zuerst ausschließen, dann einschließen = eingeschlossen!

Edit: Oder meinst du momentan nur einen Schritt? Also nur das hier:
Zitat:

alles, was zwischen (einschließlich) "hallo eins" bis (ausschließlich) "hallo zwei" steht, in RichEdit1 hinzufügen

Jumpy 8. Jun 2011 14:40

AW: TStringList, Pos, PosEx usw.311
 
Ginge es nicht sinngemäß auch so mit einer Verwaltung der RichEdits?

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

  function IsSameText(const str1, str2: string): Boolean;
  begin
    Result := AnsiStrIComp(PChar(str1), PChar(Str2)) = 0;
  end;

var
  load: tstringlist;
  switch, i: integer;
  RE : Array of TRichEdit;
begin
  load := tstringlist.create;
  try
    load.loadfromfile('C:\1.txt');
    switch := 0;
    Re[0]:=RichEdit1;
    Re[1]:=RichEdit2;
    For i=0 To load.count-1 do
      begin
      If IsSameText('hallo eins:', load[i]) Then switch:=0;
      If IsSameText('hallo zwei:', load[i]) Then switch:=1;
      Re[switch].Lines.Add(load[i])
      end
  finally
    load.Free;
  end;
end;

DeddyH 8. Jun 2011 14:44

AW: TStringList, Pos, PosEx usw.311
 
Damit würdest Du aber auch alle Zeilen vor "hallo eins" ins erste RichEdit kopieren, wenn ich das richtig sehe (switch steht ja initial auf 0).

Jumpy 8. Jun 2011 15:34

AW: TStringList, Pos, PosEx usw.311
 
Überarbeitete Version:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

  function IsSameText(const str1, str2: string): Boolean;
  begin
    Result := AnsiStrIComp(PChar(str1), PChar(Str2)) = 0;
  end;

var
  load: tstringlist;
  switch, i: integer;
  RE : Array of TRichEdit;
begin
  load := tstringlist.create;
  try
    load.loadfromfile('C:\1.txt');
    switch := -1;
    Re[0]:=RichEdit1;
    Re[1]:=RichEdit2;
    For i=0 To load.count-1 do
      begin
      If IsSameText('hallo eins:', load[i]) Then switch:=0;
      If IsSameText('hallo zwei:', load[i]) Then switch:=1;
      If switch >= 0 then Re[switch].Lines.Add(load[i])
      end
  finally
    load.Free;
  end;
end;
Aber geht das so tatsächlich, mit einem Array für Controls? Und muss ich das nicht irgendwo noch createn oder mit SetLenght dimensionieren?

DeddyH 8. Jun 2011 15:40

AW: TStringList, Pos, PosEx usw.311
 
Wenn Du weißt, dass es 2 Elemente sind, dann ist ein dynamisches Array ja witzlos, Du könntest also auch bei einem statischen bleiben. Außerdem müsstest Du nach dem Befüllen des 2. RichEdits aus der Schleife springen, sonst kopierst Du die anschließenden Abschnitte ja mit ("hallo eins" kommt in dem Beispiel ja mehrfach vor).

[edit] Rein akademische Überlegung (würde ich persönlich nicht so machen):
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

  function IsSameText(const str1, str2: string): Boolean;
  begin
    Result := AnsiStrIComp(PChar(str1), PChar(Str2)) = 0;
  end;

var
  load: tstringlist;
  switch, i: integer;
  RE : Array[0..1] of TRichEdit;
begin
  load := tstringlist.create;
  try
    load.loadfromfile('C:\1.txt');
    switch := -1;
    Re[0]:=RichEdit1;
    Re[1]:=RichEdit2;
    For i=0 To load.count-1 do
      begin
      If IsSameText('hallo eins:', load[i]) Then inc(switch);
      If IsSameText('hallo zwei:', load[i]) Then inc(switch);
      If switch in [0..1] then Re[switch].Lines.Add(load[i])
      end
  finally
    load.Free;
  end;
end;
Ich weiß allerdings nicht, ob das wirklich so funktioniert, das müsste man mal ausprobieren. [/edit]

[edit2] Nee, würde nicht klappen, wenn die Reihenfolge in der Datei nicht stimmt. [/edit2]

Jumpy 8. Jun 2011 15:44

AW: TStringList, Pos, PosEx usw.311
 
Zitat:

Zitat von DeddyH (Beitrag 1105297)
Wenn Du weißt, dass es 2 Elemente sind, dann ist ein dynamisches Array ja witzlos, Du könntest also auch bei einem statischen bleiben.
Außerdem müsstest Du nach dem Befüllen des 2. RichEdits aus der Schleife springen, sonst kopierst Du die anschließenden Abschnitte ja mit ("hallo eins" kommt in dem Beispiel ja mehrfach vor).

Zu Punkt 1 dachte ich, das dass so leicht erweiterbar wäre, d.h. man könnte leicht mehr RichEdits für mehr Hallo sager einbauen und dann ggf. auch den Vergleich dynamisch realisieren.

Zu Punkt 2: Ich dachte das wäre so gewollt, dass immer hin und her gewechselt wird.:gruebel:

DeddyH 8. Jun 2011 15:49

AW: TStringList, Pos, PosEx usw.311
 
Ich habe mir den Ausgangspost noch einmal genau durchgelesen und Du könntest Recht haben. Dann wäre Deine Vorgehensweise zumindest nicht falsch, wenn auch etwas umständlich ;). Man könnte ja auch das Array weglassen und stattdessen eine einfache RichEdit-Variable deklarieren und mit nil initialisieren. Bei Treffer dann auf das passende RichEdit switchen, weiter unten auf Assigned abfragen und schreiben.

Jumpy 8. Jun 2011 15:57

AW: TStringList, Pos, PosEx usw.311
 
JaJa. Am einfach arbeite ich ja noch:-D.
Statt immer ein Array zu switchen, einfach immer das Objekt auf das die Variable zeigt switchen. Klingt einfacher.

PredatorMask 8. Jun 2011 22:51

AW: TStringList, Pos, PosEx usw.311
 
@Jumpy #13:

Zitat:

[Error] Unit1.pas(51): For loop control variable must be simple local variable
[Error] Unit1.pas(51): Incompatible types: 'Boolean' and 'Integer'
[Error] Unit1.pas(52): Expression expected but 'BEGIN' found
[Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'

DeddyH 9. Jun 2011 07:18

AW: TStringList, Pos, PosEx usw.311
 
Die Fehlermeldungen verstehe ich nicht, rein syntaktisch ist der Code IMO in Ordnung. Hast Du ihn denn auch exakt kopiert? Achja, mach aber aus dem dynamischen Array lieber wieder ein statisches. Und es wäre nett, wenn Du noch aufklären könntest, was nach dem Schreiben in das 2. RichEdit passieren soll (siehe die Posts vor Deinem).

PredatorMask 9. Jun 2011 07:38

AW: TStringList, Pos, PosEx usw.311
 
ja, habe alles richtig kopiert. sollte das nicht auch

Delphi-Quellcode:
For i := 0 To load.count-1 do
und nich

Delphi-Quellcode:
For i=0 To load.count-1 do
heissen? ich mein, ich weiss eh nich viel, aber das scheint mir logischer. genau da setzt der cursor auch an, wenn ich f9 drücke.
und wie ein statisches array aus einem dynamischen machen? ^^

und das programm soll einfach ALLES, was in 1.txt unter "hallo 1" steht (kommt mehrmals vor, hintereinander abwechselnd!), in richedit1 hineinschreiben (also schleifenmäßig) und das gleiche, nur mit "hallo 2" und richedit2

DeddyH 9. Jun 2011 07:43

AW: TStringList, Pos, PosEx usw.311
 
Oh, stimmt, den fehlenden Doppelpunkt habe ich übersehen. Und zur Problemstellung: versuch es doch einmal wie weiter oben vorgeschlagen, indem Du eine lokale Variable vom Typ TRichEdit deklarierst und mit nil initialisierst. Wird die entsprechende Zeile gefunden, setzt Du sie auf das entsprechende RichEdit und schreibst hinein.

PredatorMask 9. Jun 2011 07:45

AW: TStringList, Pos, PosEx usw.311
 
hi

ehm danke für den tipp, sagt mir leider aber alles recht wenig. bin doch nochn neuling ^^

DeddyH 9. Jun 2011 07:49

AW: TStringList, Pos, PosEx usw.311
 
Ungetestet:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);

  function IsSameText(const str1, str2: string): Boolean;
  begin
    Result := AnsiStrIComp(PChar(str1), PChar(Str2)) = 0;
  end;

var
  load: TStringlist;
  i: integer;
  RE : TRichEdit;
begin
  RE := nil;
  load := TStringlist.Create;
  try
    load.LoadFromFile('C:\1.txt');
    for i := 0 to load.count - 1 do
      begin
        if IsSameText('hallo eins:', load[i]) then
          RE := RichEdit1
        else if IsSameText('hallo zwei:', load[i]) then
          RE := RichEdit2;
        if Assigned(RE) then
          RE.Lines.Add(load[i]);
      end;
  finally
    load.Free;
  end;
end;

Jumpy 9. Jun 2011 07:58

AW: TStringList, Pos, PosEx usw.311
 
Sorry für den Doppelpunkt. Das ist der Mist wenn man drei mal täglich zwischen Delphi und VBA hin und her wechseln / denken muss. Aber schlimmer ist, wenn ich 4 Tage hintereinander nur was in Delphi gemacht habe (Codevervollständigung mit Returntaste) und dann nach VBA wechsle (Tabulatortaste) und mir ständig mir Return die Zeilen zerhauhe.

DeddyH 9. Jun 2011 08:02

AW: TStringList, Pos, PosEx usw.311
 
*Gg* das kommt mir bekannt vor.

PredatorMask 9. Jun 2011 08:19

AW: TStringList, Pos, PosEx usw.311
 
hey jungs, letzter vorschlag funktioniert! :)

nur könntet ihr mir sagen, warum die gauge (sowie eine progressbar) ums verrecken nicht macht, was sie machen soll ?

Delphi-Quellcode:
  function IsSameText(const str1, str2: string): Boolean;
  begin
    Result := AnsiStrIComp(PChar(str1), PChar(Str2)) = 0;
  end;

var
  load: TStringlist;
  i: integer;
  RE : TRichEdit;
begin
  RE := nil;
  load := TStringlist.Create;
  gauge1.Progress := 0;
  gauge1.MaxValue := load.Count;
  label2.caption := 'work in progress ... please wait';
  try
    load.LoadFromFile('C:\1.txt');
    for i := 0 to load.count - 1 do
      begin
        gauge1.Progress := i;
        application.ProcessMessages;
        if IsSameText('hallo eins:', load[i]) then
          RE := RichEdit1
        else if IsSameText('hallo zwei:', load[i]) then
          RE := RichEdit2;
        if Assigned(RE) then
          RE.Lines.Add(load[i]);
          application.ProcessMessages;
          label1.caption := inttostr(i) + ' / ' + inttostr(load.count) + ' lines done';
      end;
  finally
    load.Free;
    label2.caption := 'waiting ...';
  end;
der "counter" funktioniert, aber die gauge nicht ... total bescheuert :|

DeddyH 9. Jun 2011 08:24

AW: TStringList, Pos, PosEx usw.311
 
Was heißt "funktioniert nicht"? Passiert gar nichts, oder stimmt die Anzeige nicht?

PredatorMask 9. Jun 2011 08:26

AW: TStringList, Pos, PosEx usw.311
 
da tut sich absolut garnichts... wunderlich, davor hats noch funktioniret

//edit: habe den fehler!! man muss
Delphi-Quellcode:
gauge1.maxvalue := load.count
NACH
Delphi-Quellcode:
load.loadfromfile()
machen (logischerweise) :D

ich danke euch allen vielmals für eure hilfe und eure bemühungen, ich werd mir mal alle lösungsvorschläge genau anschauen :)

DeddyH 9. Jun 2011 08:29

AW: TStringList, Pos, PosEx usw.311
 
Jetzt habe ich es gesehen:
Zitat:

Delphi-Quellcode:
gauge1.MaxValue := load.Count;
...
load.LoadFromFile('C:\1.txt');

Fällt Dir etwas auf im Bezug auf load.Count?

[edit] Ah, schon selbst bemerkt :) [/edit]

Sir Rufo 9. Jun 2011 08:32

AW: TStringList, Pos, PosEx usw.311
 
Setz doch mal den Gauge.Max Wert nach dem Laden der Datei, dann hast du auch einen Wert > 0 ;)

Das mit dem Label, das sich nicht aktualisiert hatten wir vor Kurzem schon mal.
Mal suchen, oder mit Label.Repaint erzwingen

DeddyH 9. Jun 2011 08:33

AW: TStringList, Pos, PosEx usw.311
 
Du bist zu spät, das Problem ist ja bereits erkannt und gelöst :)

PredatorMask 9. Jun 2011 08:51

AW: TStringList, Pos, PosEx usw.311
 
alles klar, danke jungs :thumb: funktionier jetzt alles wunderbar :)

Cirec 9. Jun 2011 09:08

AW: TStringList, Pos, PosEx usw.311
 
Hallo,
nur ganz kurtz
In D7 "AnsiSameText" ist in SysUtils

mfg

DeddyH 9. Jun 2011 09:15

AW: TStringList, Pos, PosEx usw.311
 
Das hatte ich zwar bereits hier vermutet, trotzdem Danke für die Bestätigung :thumb:.

Jumpy 9. Jun 2011 09:19

AW: TStringList, Pos, PosEx usw.311
 
Lieber TE,
you made my day.

Hintergrund: Ein MySQL-DBMS bei uns schreibt in ein SQL LOG alle Datenmanipulierenden Anfragen rein. Für mehrere Datenbanken. Und am "use DBName" kann man sehen wann er die Datenbank wechselt. Jetzt sollte ich das Log auf die DBs aufspalten. Was meinst du wie ich das gemacht habe:-D?


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:26 Uhr.

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