Autor |
Beitrag |
r@cer
Hält's aus hier
Beiträge: 13
Win 7, Ubuntu 10.10
Delphi 5 Prof., Lazarus
|
Verfasst: 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)
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; 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=1) and (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.
      
Beiträge: 1703
Erhaltene Danke: 25
Windows Vista / Windows 10
Delphi 2009 Pro (JVCL, DragDrop, rmKlever, ICS, EmbeddedWB, DEC, Indy)
|
Verfasst: So 23.10.11 13:44
Das geht mit einer TStringList viel einfacher:
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 input.LoadFromFile('C:\Quelldatei.txt');
output := TStringList.Create; try output.Text := StringReplace(input.Text, ' ', sLineBreak, [rfReplaceAll]);
output.SaveToFile('C:\Zeildatei.txt'); finally FreeAndNil(output); end; finally FreeAndNil(input); end; end;
|
|
|
r@cer 
Hält's aus hier
Beiträge: 13
Win 7, Ubuntu 10.10
Delphi 5 Prof., Lazarus
|
Verfasst: 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
      
Beiträge: 36
Erhaltene Danke: 4
WinXP
Delphi6 MySQL
|
Verfasst: So 23.10.11 20:10
Du schreibst
Delphi-Quelltext 1: 2: 3:
| repeat inc(c); until s[c]=' '; |
wenn es kein Leerzeichen gibt steigt c über alle Grenzen.
|
|
Yogu
      
Beiträge: 2598
Erhaltene Danke: 156
Ubuntu 13.04, Win 7
C# (VS 2013)
|
Verfasst: 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.
      
Beiträge: 1703
Erhaltene Danke: 25
Windows Vista / Windows 10
Delphi 2009 Pro (JVCL, DragDrop, rmKlever, ICS, EmbeddedWB, DEC, Indy)
|
Verfasst: Mo 24.10.11 09:03
|
|
|