Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Problem mit Textfile


Waldkauz - Mo 30.03.09 19:59
Titel: Problem mit Textfile
Hallo

Ich muss mich leider schon wieder wegen einer Frage melden...
Okay, also wie bereits erklärt, man klickt auf den Button3, und wenn sich das eingegebene Wort in dem jeweiligen Textfile befindet, bekommt man, je nach verbliebener Zeit gewisse Punkte (die Punkteanzahl wird in ein jeweils separates Editfeld ausgegeben).
Bei den ersten drei Funktionen klappt das einwandfrei, nur beim letzten (beim "Namen.txt") funktioniert etwas nicht.
Ich weiß aber nicht wo der Fehler liegt. Ist das textfile mit seinen 146 KB, bzw. den 8902 Wörtern zu groß?
Das textfile ist selbtverständlich im gleichen Ordner wie das Programm, und die Wörter sind jeweils eines pro zeile geordnet.
ich entschuldige mich schon im Vorfeld für den chaotischen und unprofessionellen Quelltext...


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:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
procedure TForm1.Button3Click(Sender: TObject);
var
Stadt,Land,Fluss : textfile;
Namen : textfile;
Suchen : String;
Search : String;
S : Integer;
I: Integer;
Z:Integer;
begin
      Assignfile(Stadt, 'Stadt.txt');
      Reset(Stadt);
       for S := 0 to 233 do
      begin
      ReadLn(Stadt,Suchen);
        if (Edit1.Text=Suchen) and (StrToInt(Label9.Caption)>=100then
        Edit8.Text:='30';
        if (Edit1.Text=Suchen) and (StrToInt(Label9.Caption)>=60and (StrToInt(Label9.Caption)<100then
        Edit8.Text:='20';
        if (Edit1.Text=Suchen) and (StrToInt(Label9.Caption)>=0and (StrToInt(Label9.Caption)<60then
        Edit8.Text:='10';
        if Edit1.Text='' then
        Edit8.Text:='';
        {if Copy(Edit1.Text,1,1)<> Label9.Caption then
        Edit8.Text:='';   }

        end;
        Assignfile(Land,'Land.txt');
         Reset(Land);
      for I := 0 to 241 do
      begin
      ReadLn(Land,Search);
        if (Edit2.Text=Search) and (StrToInt(Label9.Caption)>=100then
        Edit9.Text:='30';
        if (Edit2.Text=Search) and (StrToInt(Label9.Caption)>=60and (StrToInt(Label9.Caption)<100then
        Edit9.Text:='20';
        if (Edit2.Text=Search) and (StrToInt(Label9.Caption)>=0and (StrToInt(Label9.Caption)<60then
        Edit9.Text:='10';
        if Edit2.Text='' then
        Edit9.Text:='';
        
      end;
      Assignfile(Fluss,'Fluss.txt');
         Reset(Fluss);
      for I := 0 to 887 do
      begin
      ReadLn(Fluss,Search);
        if (Edit3.Text=Search) and (StrToInt(Label9.Caption)>=100then
        Edit10.Text:='30';
        if (Edit3.Text=Search) and (StrToInt(Label9.Caption)>=60and (StrToInt(Label9.Caption)<100then
        Edit10.Text:='20';
        if (Edit3.Text=Search) and (StrToInt(Label9.Caption)>=0and (StrToInt(Label9.Caption)<60then
        Edit10.Text:='10';
        if Edit3.Text='' then
        Edit10.Text:='';
      end;
       Assignfile(Namen,'Namen.txt');  //ab hier muss irgendwo der Wurm drin sein
         Reset(Namen);
         for Z := 0 to 8902 do
      begin
      ReadLn(Namen,Search);
        if (Edit4.Text=Search) and (StrToInt(Label9.Caption)>=100then
        Edit11.Text:='30';
        if (Edit4.Text=Search) and (StrToInt(Label9.Caption)>=60and (StrToInt(Label9.Caption)<100then
        Edit11.Text:='20';
        if (Edit4.Text=Search) and (StrToInt(Label9.Caption)>=0and (StrToInt(Label9.Caption)<60then
        Edit11.Text:='10';
        if Edit4.Text='' then
        Edit11.Text:='';
      end;

end;


Moderiert von user profile iconNarses: Titel geändert.


JayEff - Mo 30.03.09 20:07

user profile iconWaldkauz hat folgendes geschrieben Zum zitierten Posting springen:
Bei den ersten drei Funktionen klappt das einwandfrei, nur beim letzten (beim "Namen.txt") funktioniert etwas nicht.

Und was? :nixweiss:
user profile iconWaldkauz hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
  Assignfile(Namen, ExtractFilePath(ParamStr(0)) + 'Namen.txt');  //NIEMALS RELATIVE PFADANGABEN! KORRIGIERE DAS AUCH OBEN!
  Reset(Namen);
  while not EOF(Namen) do //Wieso die Zahl fest reincoden, wenn sich die Dateigröße ändern könnte? EOF=End of File
  begin
    ReadLn(Namen,Search);
    if (Edit4.Text=Search) and (StrToInt(Label9.Caption)>=100then
      Edit11.Text:='30';
    
    if (Edit4.Text=Search) and (StrToInt(Label9.Caption)>=60and (StrToInt(Label9.Caption)<100then
      Edit11.Text:='20';

    if (Edit4.Text=Search) and (StrToInt(Label9.Caption)>=0and (StrToInt(Label9.Caption)<60then
      Edit11.Text:='10';

    if Edit4.Text='' then
      Edit11.Text:='';
  end;

end;

Siehe meine Kommentare - Ob dein Problem damit gelöst ist? :nixweiss: Ich kenn dein Problem ja nichtmal :)


Horst_H - Mo 30.03.09 20:11

Hallo,

Du nutzt ein umständliches Verfahren, Du könntest zu Beginn des Programmes jeweils eine Stringliste laden, aber gut.

Kann es sein das Du Deine Textdateien erzeugst, öffnest und liest aber nicht mehr schliesst ( z.B.: Closefile(Stadt) ) .

Probier das mal. Man kann vielleicht nur begrenzt viele Dateien öffnen.

Gruß Horst


JayEff - Mo 30.03.09 20:24

user profile iconHorst_H hat folgendes geschrieben Zum zitierten Posting springen:
Du nutzt ein umständliches Verfahren, Du könntest zu Beginn des Programmes jeweils eine Stringliste laden, aber gut.
Und die TStringList wäre sogar schneller, getestet hiermit:

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:
var
  t:textfile;
  sl: TStringList;
  ticks, ende : Cardinal;
  buff : String;
  i : Integer;
begin
 sl := TStringList.Create;
 ticks := GetTickCount;
 sl.LoadFromFile('D:\testdb.txt');
 for i := 0 to sl.Count - 1 do
   if sl[i] = 'asd' then
     showmessage('omg');
 sl.free;
 ende := GetTickCount;
 Form1.Caption := Format('%d', [ende - ticks]);

 ticks := GetTickCount;
 AssignFile(t, 'D:\testdb.txt');
 Reset(t);
 while not EOF(t) do
 begin
  ReadLn(t, buff);
  if buff = 'asd' then
    showmessage('omg');
 end;
 ende := GetTickCount;
 Form1.Caption := Format('StringList: %s ms, textfile: %d ms', [Form1.Caption, ende-ticks]);

StringList: 16 ms, textfile: 32 ms. Klar, dass die Abfragen niemals true waren, das war natürlich beabsichtigt, wollte nur vergleichbaren code haben der auch wirklich nicht wegoptimiert wird.
Edit: Mein textfile war 1,3 MB groß und hatte verdammt viele Zeilen :mrgreen:
user profile iconHorst_H hat folgendes geschrieben Zum zitierten Posting springen:
Kann es sein das Du Deine Textdateien erzeugst, öffnest und liest aber nicht mehr schliesst
Richtig, das fehlt auch noch.


Waldkauz - Mo 30.03.09 20:46

Danke zunächst mal für eure Hilfe.
Ich habe es jetzt mit Closefile probiert.
Also es sieht jetzt so aus:
Alle Funktionien gehen, bis auf die mit Namen.
Bei der Namensfunktion schreibt es, auch bei richtiger Eingabe, keine Punkte ins Punktefeld, also muss irgendwo in dieser Funktion das Problem liegen :gruebel:
Hat es vielleicht was mit der Codierung des Textfiles zu tun?
Weil, wenn ich mich nicht irre, waren in dem Textfile auch Namen mit Sonderzeichen.


JayEff - Mo 30.03.09 20:57

user profile iconWaldkauz hat folgendes geschrieben Zum zitierten Posting springen:
Weil, wenn ich mich nicht irre, waren in dem Textfile auch Namen mit Sonderzeichen.
Solange es keine Unicode Zeichen sind, müsste das trotzdem gehen, an sonsten bin ich mir nicht sicher. Trotzdem müssten die Namen erkennbar sein. Klatsch mal eine Listbox auf dein Programm und füge in deine Schleife ListBox1.Add(Suchen);. Das macht die Schleife zwar verdammt langsam, aber wenn sie dann durchgelaufen ist, siehst du, was delphi sieht. Vielleicht wär ein Memo mit Memo1.Lines.Add besser, dann könntest du auch (durch markieren) erkennen, ob am ende der Zeilen irgendwelche leerzeichen stehen oder ähnliches. Alternativ poste mal die textdatei.
Und korrigiere das mit den relativen Pfaden! :mahn:


Waldkauz - Mo 30.03.09 21:06

Problem gelöst - es waren die Unicode-Zeichen!
Vielen Dank für eure Hilfe!


JayEff - Mo 30.03.09 21:08

user profile iconWaldkauz hat folgendes geschrieben Zum zitierten Posting springen:
Problem gelöst - es waren die Unicode-Zeichen!
Die normalen Delphi Komponenten unterstützen erst seit D2009 (?) Unicode, du wirst andere Komponenten nutzen müssen, wenn du Unicode anzeigen willst. Ich hab gehört, es gibt da welche mit dem Namen Suche in: Delphi-Forum, Delphi-Library TNT ... :nixweiss:


Waldkauz - Mo 30.03.09 21:10

user profile iconJayEff hat folgendes geschrieben Zum zitierten Posting springen:
user profile iconWaldkauz hat folgendes geschrieben Zum zitierten Posting springen:
Problem gelöst - es waren die Unicode-Zeichen!
Die normalen Delphi Komponenten unterstützen erst seit D2009 (?) Unicode, du wirst andere Komponenten nutzen müssen, wenn du Unicode anzeigen willst. Ich hab gehört, es gibt da welche mit dem Namen Suche in: Delphi-Forum, Delphi-Library TNT ... :nixweiss:


Ist nicht so schlimm. Die Wahrscheinlichkeit, dass beim Tag der offenen Tür Schweden aufkreuzen, is relativ gering ^^