String-Problem (text-datei auslesen)
spacer
Autor Nachricht
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 markieren
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=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
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Werbung ausblenden? Dann registriere Dich kostenlos. Weitere Gründe für eine Registrierung.


Werbung ausblenden? Dann registriere Dich kostenlos. Weitere Gründe für eine Registrierung.
Andreas L.
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic starofftopic starofftopic star
Beiträge: 1671
Erhaltene Danke: 14

Windows Vista Home Premium 32Bit
RAD Studio 2009 Pro
BeitragVerfasst: So 23.10.11 13:44 
Das geht mit einer TStringList viel einfacher:

ausblenden Delphi-Quelltext markieren
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.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
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 ;)
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Singlepin
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 32
Erhaltene Danke: 2

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

wenn es kein Leerzeichen gibt steigt c über alle Grenzen.
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Yogu
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic star
Beiträge: 2544
Erhaltene Danke: 137

Windows 7 Home Premium
Visual C# 2010 Express
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
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
Andreas L.
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starhalf offtopic starofftopic starofftopic star
Beiträge: 1671
Erhaltene Danke: 14

Windows Vista Home Premium 32Bit
RAD Studio 2009 Pro
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 markieren
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
 
Antworten mit Zitat Beitrag melden
Private Nachricht sendenPosting in privater Nachricht zitieren
home home