unistd.h read () Funktion: Wie liest man eine Datei Zeile für Zeile?

8

Was ich tun muss, ist die Lesefunktion von unistd.h, um eine Datei zu lesen Zeile für Zeile. Ich habe das im Moment:

%Vor%

Dies liest jedoch bis zum Ende der Datei oder bis zur Größe der Anzahl der Bytes. Gibt es eine Möglichkeit, dass ich es Zeile für Zeile lesen kann, indem ich an einer neuen Zeile stehe? Die Zeilen sind alle von variabler Länge.

Ich darf nur diese beiden Header-Dateien:

%Vor%

Der Sinn der Übung besteht darin, eine Datei zeilenweise einzulesen und gib jede Zeile so aus, wie sie eingelesen wird. Im Prinzip, um die fgets () nachzuahmen und fputs () - Funktionen.

    
Will 27.02.2010, 20:00
quelle

7 Antworten

8

Sie können Zeichen für Zeichen in einen Puffer lesen und nach den Zeilenumbruch-Symbolen suchen ( \r\n für Windows und \n für Unix-Systeme).

    
Otto Allmendinger 27.02.2010, 20:05
quelle
4

Sie sollten einen Puffer erstellen, der doppelt so lang ist wie die längste Zeile, die Sie unterstützen, und Sie müssen den Pufferstatus überwachen.

Grundsätzlich werden Sie jedes Mal, wenn Sie nach einer neuen Zeile gefragt werden, von Ihrer aktuellen Pufferposition aus nach einem Marker für die Endzeile suchen. Wenn Sie einen finden, gut, das ist Ihre Linie. Aktualisieren Sie Ihre Pufferzeiger und kehren Sie zurück.

Wenn Sie Ihre maximale Länge treffen, geben Sie eine abgeschnittene Linie zurück und ändern Ihren Status zum Löschen. Wenn Sie das nächste Mal angerufen werden, müssen Sie bis zum nächsten Zeilenende abbrechen und dann Ihren normalen Lesezustand eingeben.

Wenn Sie das Ende dessen, was Sie eingelesen haben, angeklickt haben, müssen Sie einen anderen Maxline-Zeichen einlesen und am Anfang des Puffers einpacken, wenn Sie den unteren Rand berühren (dh Sie müssen möglicherweise zwei Leseaufrufe machen) und dann weiter scannen.

Bei allen obigen Annahmen wird davon ausgegangen, dass Sie eine maximale Zeilenlänge festlegen können. Wenn das nicht möglich ist, müssen Sie mit dynamischem Speicher arbeiten und sich sorgen, was passiert, wenn ein Puffer-malloc ausfällt. Außerdem müssen Sie immer die Ergebnisse des Lesens überprüfen, wenn Sie das Ende der Datei beim Lesen in den Puffer gefunden haben.

    
swestrup 27.02.2010 20:49
quelle
1

Leider ist die Lesefunktion für diese Art von Eingabe nicht wirklich geeignet. Angenommen, dies ist eine künstliche Anforderung von Interview / Hausaufgaben / Übung, können Sie versuchen, zeilenbasierte Eingabe zu simulieren, indem Sie die Datei in Blöcken lesen und sie auf dem Newline-Zeichen selbst aufteilen. Sie können eine statische Positionsanzeige verwenden, wenn Sie die Verwendung der Funktion sorgfältig dokumentieren.

    
Mark B 27.02.2010 20:43
quelle
1

Wenn Sie mit read() genau eine Zeile lesen müssen (und nicht überschreiten), ist die einzige allgemein anwendbare Methode, das zu tun, indem Sie jeweils 1 Byte lesen und eine Schleife durchlaufen, bis Sie ein Zeilenvorschubbyte erhalten. Wenn Ihr Dateideskriptor jedoch auf ein Terminal verweist und sich im Standardmodus (kanonisch) befindet, wartet read auf einen Zeilenumbruch und gibt weniger als die angeforderte Größe zurück, sobald eine Zeile verfügbar ist. Es kann jedoch mehr als eine Zeile zurückgeben, wenn Daten sehr schnell ankommen, oder weniger als eine Zeile, wenn der Puffer Ihres Programms oder der interne Terminalpuffer kürzer als die Zeilenlänge ist.

Wenn Sie wirklich keinen Überschritt vermeiden müssen (was manchmal wichtig ist, wenn Sie möchten, dass ein anderer Prozess / Programm den Dateideskriptor erbt und das Lesen an der Stelle aufhört, an der Sie aufgehört haben), würde ich stdio functions oder verwenden Ihr eigenes Puffersystem. Die Verwendung von read für zeilenbasiertes oder Byte für Byte IO ist sehr schmerzhaft und schwer zu korrigieren.

    
R.. 26.07.2010 13:17
quelle
0

Das ist eine gute Frage, aber nur die Lesefunktion zuzulassen, hilft nicht! : P

Lesen Sie die Aufrufe, um eine feste Anzahl von Bytes zu erhalten, suchen Sie das Zeichen \ n, geben Sie einen Teil der Zeichenkette zurück (bis \ n) und speichern Sie den Rest (außer \ n \) dem nächsten Zeichendateiblock vorangestellt.

Verwenden Sie dynamischen Speicher.

Größere Größe des Puffers, weniger gelesene Aufrufe (das ist ein Systemaufruf, also keine billige, aber heutzutage gibt es preemptive Kernel).

...

Oder repariere einfach eine maximale Zeilenlänge und benutze fgets, wenn du schnell sein musst ...

    
Luca 27.02.2010 20:09
quelle
0

Nun, es wird Zeile für Zeile von einem Terminal gelesen.

Einige Auswahlmöglichkeiten sind:

  • Schreiben Sie eine Funktion, die lesen verwendet, wenn es keine Daten mehr gibt, sondern nur eine Zeile nach dem anderen an den Aufrufer
  • zurückgibt
  • Verwenden Sie die Funktion in der Bibliothek, die genau das tut: fgets() .
  • Lese nur ein Byte nach dem anderen, damit du nicht zu weit gehst.
DigitalRoss 27.02.2010 20:11
quelle
0

Wenn Sie die Datei im Textmodus öffnen, wird Windows "\ r \ n" automatisch in "\ n" übersetzt, während die Datei gelesen wird.

Wenn Sie mit Unix arbeiten, können Sie die nicht standardmäßige 1 gcc 'getline ()' Funktion verwenden.

1 Die Funktion getline () ist standardmäßig in POSIX enthalten 2008.

    
Martin Beckett 27.02.2010 20:10
quelle

Tags und Links