Autor Beitrag
r@cer
Hält's aus hier
Beiträge: 13

Win 7, Ubuntu 10.10
Delphi 5 Prof., Lazarus
BeitragVerfasst: So 23.10.11 13:36 
Hi :)

ich wollte mal ein kleines Programm schreiben, dass aus einer einfachen Text-Datei den sich darin befindenden Text ausliest, und dessen Wörter in einer neuen Datei auflistet (also pro Zeile ein Wort).
Hier mal mein bisheriger code:
(Erklärung und mein Problem erfolgen darunter)

ausblenden volle Höhe 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:
procedure TForm1.Button1Click(Sender: TObject);
var f,wordlist : TextFile;
    s,t : string;
    //list : TStringList;
    a,b,c,d : integer;
begin

  a:=0;
  assignfile(f, 'text.txt');
  Reset(f);
  while not EoF(f) do
    begin
    ReadLn(f);
    Inc(a);
  end;
  Reset(f);

  for b:=1 to a do begin
    assignfile(f, 'text.txt');
    reset(f);
    readln(f, s);
    repeat
      c:=0;
      repeat
        inc(c);
      until s[c]=' ';
      if (c=1and (s[1]=' 'then begin
        d:=length(s);
        s:=copy(s,2,d);
      end else begin
        t:=copy(s,1,c-1);
        AssignFile(wordlist, 'wordlist.txt');
        rewrite(wordlist);
        writeln(wordlist, t);
        closeFile(wordlist);
        d:=length(s);
        s:=copy(s,c+1,d);
      end;
    until length(s)=0;
  end;
end;


Von Zeile 8 - 16 lasse ich das Programm überprüfen, wie viele Zeilen der Text eigentlich hat. Diese Zeilenanzahl welche ich in der Variablen "a" speichere, verwende ich dann für meine for-Schleife (Zeile 18-40). Hier wird also pro Schleifendurchlauf eine Zeile des Textes in meinem String "s" abgespeichert und dann deren Wörter in den beiden repeat-schleifen in dem anderen String "t" abgelegt und im selben Durchgang (der repeat-schleife) auch gleich in meine "wordlist" geschrieben.
Wobei mir hier soeben aufgefallen ist, dass ich glaube ich bei der for-Schleifen noch etwas vergessen habe: Wenn nicht nach jedem Durchlauf die zuletzt verwendete Zeile aus der Textdatei gelöscht wird, liest das Programm immer wieder die gleiche Zeile (nämlich Zeile 1) aus. Aber ich denke, das bekomme ich noch hin :).

Mein eigentliches Problem: Wenn ich das Programm ausführen möchte und auf den Button klicke, kommt immer folgende Fehlermeldung (und Zeile 26 wird blau hinterlegt):
Zitat:

Im Projekt Project1.exe ist eine Exception der Klasse EAccessViolation aufgetreten. Meldung: 'Zugriffsverletzung bei Adresse 0044074D in Modul 'Project1.exe'. Lesen von Adresse 002C4000'. Prozeß wurde angehalten. Mit Einzelne Anweisung oder Start fortsetzen.


vielleicht kann mir ja jemand dabei helfen :)

gruß
r@er
Andreas L.
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1703
Erhaltene Danke: 25

Windows Vista / Windows 10
Delphi 2009 Pro (JVCL, DragDrop, rmKlever, ICS, EmbeddedWB, DEC, Indy)
BeitragVerfasst: So 23.10.11 13:44 
Das geht mit einer TStringList viel einfacher:

ausblenden 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:
var
  input, output: TStrings;
begin
  input := TStringList.Create;
  try
    // Quelldatei laden
    input.LoadFromFile('C:\Quelldatei.txt');

    output := TStringList.Create;
    try
      // Alle Leerzeichen in Zeilenumbrüche umwandeln
      output.Text := StringReplace(input.Text, ' ', sLineBreak, [rfReplaceAll]); 

      // In Zieldatei speichern
      output.SaveToFile('C:\Zeildatei.txt'); 
    finally
      FreeAndNil(output);
    end;
  finally
    FreeAndNil(input);
  end;
end;

// Kann man natürlich auch alles mit einer TStringList machen. So ist es halt besser verständlich.
r@cer Threadstarter
Hält's aus hier
Beiträge: 13

Win 7, Ubuntu 10.10
Delphi 5 Prof., Lazarus
BeitragVerfasst: So 23.10.11 17:47 
danke :)
ich hab das mal ausprobiert und bekam gleich wieder eine Fehlermeldung: "Undefinierter Bezeichner: 'sLineBreak'"
Ich nehme mal an, dass es daran liegt, dass ich Delphi 5 verwende und ich hierfür irgend ein zusätzliches Paket oder eine Komponente nachinstallieren müsste ...

Aber nochmal zu meinem geposteten Code, denn auch wenn die Version von Andreas L. für viele einfacher erscheinen mag, würde es mich trotzdem interessieren, was an meinem code falsch ist und wie man es beheben kann. Denn auch wenn es vielleicht umständlicher ist, habe ich es dennoch selbst geschrieben und verstehe dieses Programm auch. Und das ist mir auch am wichtigsten. Denn schließlich lerne ich noch programmieren und wenn ich mir dann mal die Mühe mache und versuche ein Programm selbst zu schreiben, bringt es mir eben rein gar nichts, wenn mir jemand anstatt mir bei meinem Code zu helfen einen komplett anderen hier postet der zwar viel kürzer ist, aber voll ist von begrifflichkeiten von denen ich noch nie was gehört habe - wie z.B. sLineBreak, rfReplaceAll oder FreeAndNil. Ich nehme mal an das sind irgendwelche vorgefertigten funktionen die das leben eines Programmierers etwas einfacher gestalten sollen. Aber für mich ist das genauso, wie in der Schule im Matheunterricht, wenn der Lehrer eine neue Formel ohne Herleitung an die Tafel schreibt und die Schüler das dann so akzeptieren und anwenden müssen aber keine Ahnung haben was eigentlich dahinter steckt. Und das finde ich eben nicht so gut, da es mir ums verständnis geht.
Deswegen schreibe ich jetzt, da ich quasi noch am lernen bin, lieber mal ein paar Zeilen mehr und habe aber dafür den vollen Durchblick ;)

also wenn jemand den Fehler in meinem Programm findet bin ich weiterhin froh um jeden Tipp :)
@Andreas
bin dir natürlich trotzdem dankbar für deine Mühe :)
war nur konstruktiv gemeint ;)
Singlepin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 36
Erhaltene Danke: 4

WinXP
Delphi6 MySQL
BeitragVerfasst: So 23.10.11 20:10 
Du schreibst
ausblenden Delphi-Quelltext
1:
2:
3:
repeat
 inc(c);
until s[c]=' ';

wenn es kein Leerzeichen gibt steigt c über alle Grenzen.
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2598
Erhaltene Danke: 156

Ubuntu 13.04, Win 7
C# (VS 2013)
BeitragVerfasst: So 23.10.11 22:23 
Hallo,

um zu prüfen, ob das Dateiende erreicht ist, solltest du Eof(f) verwenden, nicht schauen, ob der String leer ist. Vielleicht ist s undefiniert, wenn das Dateiende erreicht ist, was eine häufige Ursache der Zugriffsverletzung ist.

Allerdings sollte man sich doch gerade in der Lernphase auch neue Dinge anschauen und in der Hilfe nachschlagen, um zu sehen, ob man damit zurechtkommt. Aber natürlich ist es auch wichtig, die Fehler am eigenen Code zu finden.

Grüße,
Yogu
Andreas L.
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 1703
Erhaltene Danke: 25

Windows Vista / Windows 10
Delphi 2009 Pro (JVCL, DragDrop, rmKlever, ICS, EmbeddedWB, DEC, Indy)
BeitragVerfasst: Mo 24.10.11 09:03 
user profile iconr@cer hat folgendes geschrieben Zum zitierten Posting springen:
wie z.B. sLineBreak, rfReplaceAll oder FreeAndNil.

sLineBreak ist lediglich eine Konstante für einen Zeilenumbruch, alternativ kannst du auch #13#10 schreiben. rfReplaceAll gibt an, dass die Funktion StringReplace alle vorkommen ersetzen soll. Lässt du den Wert weg, wird nur das erste Vorkommen ersetzt.
FreeAndNil ist eine Prozedur die das übergebene Objekt freigibt und den Zeiger der Variable auf nil also nichts stellt. Ist identisch mit folgendem Code:
ausblenden Delphi-Quelltext
1:
2:
  input.Free;
  input := nil;


user profile iconr@cer hat folgendes geschrieben Zum zitierten Posting springen:
Deswegen schreibe ich jetzt, da ich quasi noch am lernen bin, lieber mal ein paar Zeilen mehr und habe aber dafür den vollen Durchblick ;)


Natürlich ist es wichtig auch die von dir verwendeten Befehle zu kennen und den Fehler in deinem Code zu finden. Ich wollte nur einen alternativen Lösungsweg aufzeigen, der dir später sicherlich mal nützlich sein wird. Mit TStringList kann man noch viel mehr anstellen, stell es dir wie eine Kopie der Textdatei vor auf die du u. a. zeilenweise zugreifen kannst. Für mehr Infos: docwiki.embarcadero..../Classes.TStringList