Entwickler-Ecke
Dateizugriff - Zeilenanzahl in txt Datei
der organist - Mo 22.12.08 13:02
Titel: Zeilenanzahl in txt Datei
Hi Leutz,
wie bekomme ich die Zeilenanzahl einer TextFile heraus, ohne sie in iergendeine Komponente zu laden?
Thx, MfG
Moderiert von
Christian S.: Topic aus Delphi Language (Object-Pascal) / CLX verschoben am Mo 22.12.2008 um 12:04
chrisw - Mo 22.12.08 13:22
Ich würde die Datei laden, zeilenweise lesen, Zähler hochzählen.
ala:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| function ZaehleZeilen(filename: String) : Integer; var F : TextFile; S : String; begin AssignFile(F,filename); Reset(F); Result := 0; while not Eof(F) do begin ReadLn(F,S); inc(Result); end; CloseFile(F); end; |
Delete - Mo 22.12.08 13:31
Oder mit einer TStringlist:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
| function ZaehleZeilen(const Filename: String) : Integer; var sl: TStringlist; begin if not FileExists(Filename) then Result := -1 else begin sl := TStringlist.Create; try sl.LoadFromFile(Filename); Result := sl.Count; finally sl.Free; end; end; end; |
chrisw - Mo 22.12.08 13:33
Ja, wobei man sich hier streiten kann, ob TStringList eine Komponente ist.
Delete - Mo 22.12.08 13:35
Klasse ja, Komponente nein.
MSCH - Mo 22.12.08 13:50
Via Blockread/Blockwrite - geht am schnellsten und dann nur #10#13 zählen.
TStringList verbraucht Speicher und ist nicht sooo performant.
:-)Msch
Delete - Mo 22.12.08 14:00
Das ist zweifellos richtig, aber dann sollte man auch Fehlerfälle behandeln.
der organist - Mo 22.12.08 17:04
gibts da keine andere Möglichkeit??
der organist - Mo 22.12.08 17:09
erst mal, am einfachsten finde ich die Lösung von chrisw. Danke dafür.
Danke auch an alle anderen, die sich hier die Mühe gegeben haben.
Blackheart666 - Mo 22.12.08 17:50
der organist hat folgendes geschrieben : |
erst mal, am einfachsten finde ich die Lösung von chrisw. Danke dafür.
Danke auch an alle anderen, die sich hier die Mühe gegeben haben. |
Obwohl doch die bessere und wohl auch einfachere Variante die von
DeddyH ist.
delphi10 - Mo 22.12.08 18:01
Mal angenommen, man hätte ein konstante Zeilenbreite von 100 Zeichen, dann ginge es auch so:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| Var F : File; const Zeilenbreite : Integer = 100; . . AssignFile(F,'Name'); Reset(f,Zeilenbreite); x := FileSize(F); CloseFile(F); |
X gibt die Anzahl der Datensätze in der Datei F an. Durch Reset(f,100), wird ein Datensatz auf 100 Zeichen festgelegt.
Ja, zugegeben. Konstante Zeilenbreite kommt wohl eher selten vor. Aber schnell ist es..!
cu Delphi10
Delete - Mo 22.12.08 18:51
Um das einmal zu komplettieren (speicherschonende Variante mit Fehlerbehandlung):
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22:
| function ZaehleZeilen(const filename: String) : Integer; var F : TextFile; begin Result := -1; if FileExists(filename) then begin AssignFile(F,filename); {$I-} Reset(F); {$I+} if IOResult = 0 then begin Result := 0; while not Eof(F) do begin ReadLn(F); inc(Result); end; CloseFile(F); end; end; end; |
jaenicke - Mo 22.12.08 19:52
Blackheart666 hat folgendes geschrieben : |
Obwohl doch die bessere und wohl auch einfachere Variante die von DeddyH ist. |
Was ist daran besser die komplette Datei erst in den Speicher zu laden, wenn du die dort gar nicht brauchst? :gruebel:
alzaimar - Mo 22.12.08 20:14
jaenicke hat folgendes geschrieben : |
Was ist daran besser die komplette Datei erst in den Speicher zu laden, wenn du die dort gar nicht brauchst? :gruebel: |
Wir haben genug Speicher, es tut keinem weh, ist einfach hingetippt, hinreichend stabil (da geprüfter Code verwendet wird) und funktioniert, ohne groß drüber nachzudenken... Wenn das kein Grund ist.
Du kannst ja eine allgemeingültige Klasse zum zählen von Zeilen in beliebig großen Textdateien schreiben. Dann würde ich per TFileStream sehr große Blöcke einlesen und die #13#10 zählen (wurde schon erwähnt). Dabei müssen blockboundaries berücksichtigt werden (#13 am Ende des aktuellen und #10 am Anfang des nächsten Blockes) usw. Das ist aber nicht trivial und ein eindeutiger Overkill.
jaenicke - Mo 22.12.08 20:20
Eine einfache Lösung, die ohne die Speicherverwendung auskommt, wurde ja bereits gepostet. :roll:
alzaimar - Mo 22.12.08 20:25
jaenicke hat folgendes geschrieben : |
Eine einfache Lösung, die ohne die Speicherverwendung auskommt, wurde ja bereits gepostet. :roll: |
Die nicht sonderlich performant ist :roll: :wink:
Delete - Mo 22.12.08 20:25
Wünscht Ihr Euch zu Weihnachten eigentlich Erbsen zum Zählen oder lieber Haare zum Spalten? :mrgreen:
alzaimar - Mo 22.12.08 20:28
Spielverderber :schmoll:
jaenicke - Mo 22.12.08 20:28
Ich nehm die Erbsen :D.
jaenicke - Mo 22.12.08 21:44
Hmm, lecker die 303 Erbsen. :D
der organist - Di 23.12.08 00:11
momentan sieht meine Lösung so aus, will aber nich richtig funzen :(. Vllt ist auch einfach mein Ansatz falsch. Wichtig ist, dass in der letzten Zeile des Dokumentes "END." steht, damit ich weiss (besser noch, damit das Programm weiss), wann die Datei zu Ende ist:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7:
| while HellFreezes do begin ReadLn(input, Line); inc(Finish); if Line = 'END.' then begin Hellfreezes:=false; end; end; |
HellFreezes ist eine Booleanariable, die voher auf
True gesetzt wurde,
input die Textdatei, ich hab auch schön
AssignFile benutzt, naja und
Line ist ein
String, wer hätte es gedacht.
jaenicke - Di 23.12.08 00:36
Das Programm weiß das auch so.
DeddyH hat folgendes geschrieben : |
|
Wenn du die Zeile nicht mitzählen willst, dann zieh einfach am Ende 1 ab von der Zahl.
Delete - Di 23.12.08 03:31
Naja, ganz so einfach ist es denn nun doch nicht, der Inhalt der Zeile müsste dann noch geprüft werden. Das könnte dann so aussehen:
Delphi-Quelltext
1:
| while not Eof(F) and (AnsiLowerCase(trim(Zeile)) <> 'end.') do |
Wobei die Zeile dann im Gegensatz zu meinem letzten Beispiel doch wieder in einer Stringvariablen gepuffert werden muss.
jaenicke - Di 23.12.08 04:50
Warum ist es nicht so einfach? Wenn das "end." in der letzten Zeile steht (das sagte er ja), dann muss das doch gar nicht geprüft werden. :nixweiss:
Einfach bis zum Ende der Datei die Zeilen zählen und fertig, dass in der letzten Zeile dann das "end." steht ändert doch nix an der Zeilenanzahl. :nixweiss:
Delete - Di 23.12.08 17:35
Und öffnest Du die Datei, fügst ein oder zwei Zeilenumbrüche hinzu, funktioniert das Ganze anscheinend nicht mehr. Wieso verlasst Ihr Euch eigentlich immer darauf, dass alles schon irgendwie stimmen wird?
jaenicke - Di 23.12.08 17:39
Ich habe Vorbedingungen und Nachbedingungen, und angegeben war die Vorbedingung, dass "end." in der letzten Zeile steht, nicht, dass danach noch Leerzeichen kommen. Also muss ich um die Nachbedingung zu erreichen auch nicht davon ausgehen, dass die Vorbedingung nicht erfüllt war und nach der dann doch nicht letzten Zeile noch leere kommen oder ähnliches.
Wenn die Spezifikation der Datei doch nicht gestimmt hat muss das eben angepasst werden. Aber zunächst habe ich keinen Grund an einer Aussage zu zweifeln. :nixweiss:
Delete - Di 23.12.08 17:47
Ich geb' s auf.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!