Ich habe eine Datei, in der ich ohne eine Verarbeitung der aktuellen Zeile iterieren möchte. Nach was ich suche, ist der beste Weg, zu einer bestimmten Zeile einer Textdatei zu gehen. Zum Beispiel scheint das Speichern der aktuellen Zeile in einer Variablen nutzlos, bis ich die vorher festgelegte Zeile erreiche.
Beispiel:
Datei.txt
%Vor% Normalerweise, um here
zu erhalten, hätte ich etwas wie folgt gemacht:
Aber fgets
muss drei Zeile sinnlos lesen und currentLine
muss foo
, fooo
und fo
speichern.
Gibt es einen besseren Weg dies zu tun, wenn man weiß, dass here
Zeile 4 ist? Etwas wie ein go to
, aber für Dateien?
Sie können nicht direkt auf eine bestimmte Zeile einer Textdatei zugreifen (es sei denn, alle Zeilen haben die gleiche Größe in Bytes und UTF8 überall ein Unicode-Zeichen kann eine variable Anzahl von Bytes annehmen, 1 bis 6. In den meisten Fällen haben Zeilen unterschiedliche Länge - verschieden von einer Zeile zur nächsten. Sie können also fseek nicht verwenden (weil Sie den Dateiversatz nicht im Voraus kennen).
> Allerdings enden Zeilen (zumindest auf Linux-Systemen) mit \n
(dem Newline-Zeichen). So könnten Sie byteweise lesen und zählen:
Sie müssen dann nicht die gesamte Zeile speichern.
Sie könnten also auf diese Weise die Zeile 45 erreichen (mit while ((c=fgetc(file)) != EOF) && linecount<45)
...) und erst dann ganze Zeilen mit fgets
oder besser lesen, noch getline (3) auf POSIX-Systemen (siehe dies Beispiel). Beachten Sie, dass die Implementierung von fgets
oder getline
wahrscheinlich oberhalb von fgetc
erstellt wird oder zumindest etwas Code mit ihr teilt. Denken Sie daran, dass <stdio.h>
gepuffert ist, siehe setvbuf (3 ) und verwandte Funktionen.
Ein anderer Weg wäre, die Datei in zwei Durchgängen zu lesen. Ein erster Durchlauf speichert den Offset (unter Verwendung von ftell (3) ...) von jedem Zeilenanfang in einer effizienten Datenstruktur (ein Vektor, eine Hashtabelle, ein Baum ...). Ein zweiter Durchlauf verwendet diese Datenstruktur, um den Offset (des Zeilenanfangs) abzurufen. Verwenden Sie dann fseek ( 3) (mit diesem Offset).
Ein dritter, POSIX-spezifischer Weg wäre, die Datei mit mmap (2 ) in Ihren virtuellen Adressraum (dies funktioniert gut für nicht zu große Dateien, zB von weniger als einigen Gigabyte). Vorsicht (Sie müssen möglicherweise mmap
eine extra Endseite eingeben, um sicherzustellen, dass die Daten mit Nullbyte abgeschlossen sind), dann können Sie strchr (3) mit '\n'
PS. BTW, der Begriff der Linien (und die End-of-Line-Marke) variieren von einem Betriebssystem zum nächsten. Unter Linux ist das Ende der Zeile ein \n
-Zeichen. Auf Windows-Zeilen wird gemunkelt, dass sie mit \r\n
usw. enden ...
A FILE *
in C ist ein Stream von char
s. In einer suchbaren Datei können Sie diese char
s mit dem Dateizeiger mit fseek()
adressieren. Aber abgesehen davon gibt es keine "Sonderzeichen" in Dateien, ein Newline ist nur ein anderes normales Zeichen.
Kurz gesagt, nein, Sie können nicht direkt zu einer Zeile einer Textdatei springen, solange Sie die Längen der Zeilen nicht im Voraus kennen.
Dieses Modell in C entspricht den Dateien, die von typischen Betriebssystemen bereitgestellt werden. Wenn Sie darüber nachdenken, die Startpunkte einzelner Zeilen zu kennen, müsste Ihr Dateisystem diese Informationen irgendwo speichern. Dies würde bedeuten, Textdateien speziell zu behandeln.
Was Sie tun können , zählt jedoch nur die Zeilen anstelle des Mustervergleichs, etwa so:
%Vor%Tags und Links c io fgets file file-processing