So lesen Sie eine Textdatei in c. Arbeiten mit Textdateien in C

Notieren Sie Informationen in Textdatei wir haben es bereits gelernt. – Wenn Sie nicht wissen, wie es geht, lesen Sie den vorherigen Artikel. Es wird ausführlich erzählt und beschrieben

Was aber, wenn die Datei bereits existiert und wir zur Verarbeitung Informationen daraus lesen müssen? Zum Glück ist das auch ganz einfach. Ich möchte Sie daran erinnern, dass es mehrere Möglichkeiten gibt, diese Aufgabe umzusetzen; ich habe nur eine davon beschrieben. Aus irgendeinem Grund scheint mir persönlich die beschriebene am einfachsten zu verstehen zu sein.

#enthalten

int main()
{
char s1 //Die Variable liest die Zeichenfolge
ifstream in („C:\\\FromC\\myfile.txt“ ); //Öffnen Sie die Datei, um Informationen zu lesen
in >>s1 ; //lies die Zeile
in.close() // Schließen der Datei

cout<Geben Sie den Wert aus s1 zum Bildschirm
return 0 ;
}

Hier ist das einfachste Programm zum Lesen der ersten Zeile aus einer Textdatei, die sich entlang des Pfads befindet
C:\\\FromC\\meineDatei.txt –
Da dies eine Fortsetzung des vorherigen Artikels ist, habe ich mich entschieden, die Datei zu verwenden, die wir dort erstellt haben. Damit sollte es wahrscheinlich keine Schwierigkeiten geben.
Aber kommen wir zurück zum Code. Zuerst öffnen wir die Datei, um Informationen daraus zu lesen, dazu verwenden wir den Befehl ifstream In Klammern geben wir wie ich entweder den Dateinamen oder den Pfad zur Datei an. („C:\\\FromC\\meineDatei.txt“ );
Als wir eine Datei öffneten, um etwas daraus zu lesen, deklarierten wir eine Variable wie char –
char s1
Jetzt müssen wir der Variablen nur noch den Wert des Strings aus der Datei zuweisen. Wir machen das als Team In
Achten Sie auf die spitzen Klammern in >>
Eigentlich sollte aus den Kommentaren zum Programmcode klar hervorgehen, dass wir ihn nachschreiben müssen, damit die Variable den gelesenen Wert zuweisen kann in >>
in >>s1 ;

Dies scheint keine besonders schwierige Aufgabe zu sein, insbesondere wenn Sie das Material aus dem vorherigen Artikel bereits perfekt beherrschen und anwenden können – alles ist absolut gleich, nur 2 Befehle sind unterschiedlich

Erstellen einer Datei und Schreiben von C++-Informationen in diese

ofstream aus ( Dateiname );
aus<< (Zu schreibender String);
aus.schließen();
=============================

Lesen von Text aus einer Datei und Drucken von Text auf dem Bildschirm in C++

ifstream In (Dateiname );
In>> (Die Zeile lesen);
In.schließen();(Schließen Sie die Datei)
============================
Lass uns schreiben ein einfaches Programm, das Tastaturtexteingaben liest und in eine Datei schreibt:

#enthalten
#enthalten

int main()
{
\\ 3 zukünftige Zeilen
clrscsr(); // Den Bildschirm löschen

cout<<“Wwedi pervuu stroku” ; cin >>a ; endl ;
cout<<“Wwedi wtoruu stroku” ; cin >>b ; endl ;
cout<<“Wwedi tretuu stroku” ; cin >>c ; endl ;
clrscr(); //

/*Beginne mit der Datei zu arbeiten*/
ofstream out („C:\\\FromC\\myfile.txt“ ); //Öffnen einer Datei zum Schreiben
aus<Schreiben Sie die erste Zeile auf
aus<Schreiben Sie die zweite Zeile
aus<Schreiben Sie die dritte Zeile auf
out.close(); // Schließen der Datei

//Variablen zurücksetzen

für (int i =0 ;i<=255 ;i ++)
(a =*““ ; b =*““ ; c =*““ ;)


ifstream in(„C:\\\FromC\\meineDatei.txt“ );
in >>a >>b >>c ; //Wir lesen jede neue Zeile in eine neue Variable
in.close(); // Schließen der Datei

/* */

für (i =0 ;a !=*““ ;i ++)
{
if (i >sizeof(a )) brechen ;
cout<

}
cout<<“\n” ; \\

/* */


{
if (i >sizeof(b)) brechen ;
cout<
}
cout<<“\n” ; \\ Der Cursor wurde in eine neue Zeile verschoben

/* */

für (i =0 ;с !=*““ ;i ++)
{
if (i >sizeof(c )) brechen ;
cout<<с ;
}

return 0 ;
}
===================

In den obigen Beispielen gibt es ein solches RIESIG Mangel. Wenn wir versuchen, eine Zeile mit Leerzeichen einzugeben, funktioniert das Programm nicht wie gewünscht. Wahrscheinlich sind nicht nur ich, sondern auch viele andere Menschen auf diesen Fehler gestoßen. Deshalb belasse ich den falschen Code, damit Sie sehen können, was auf Sie zukommen könnte.

Da es zu Hause keine Bücher gibt, begann ich erneut, das Internet zu durchsuchen und fand jede Menge raffinierten Unsinn aller Art. Aber irgendwie habe ich eine Lösung für mein Problem gefunden.
Es hat geholfen, dass ich das gelesen habe cout unterstützt seine Methoden. Und im Internet finden sich alle Hinweise zur Nutzung der Funktion getline Zum Glück habe ich sehr schnell herausgefunden, wie man diese Funktion nutzt, und sie dann im Code verwendet.
Im Allgemeinen lohnt es sich, diese Funktion zu erwähnen und zu beschreiben, aber bisher verstehe ich sie nicht wirklich. Ich verstehe nur, dass sie verwendet werden muss und wie, also werde ich ein korrekteres Beispiel für die Entwicklung unseres Programms geben :

#enthalten
#enthalten

int main()
{
char a,b,c; \\ 3 zukünftige Zeilen
clrscsr(); // Den Bildschirm löschen

/* Werte für Variablen eingeben*/

cout<<“Wwedi pervuu stroku” ; cin.getline(a,sizeof(a)); endl ;
cout<<“Wwedi wtoruu stroku” ; cin.getline(a,sizeof(b)); endl ;
cout<<“Wwedi tretuu stroku” ; cin.getline(a,sizeof(c)); endl ;
clrscr(); //Nach Eingabe der Werte wurde der Bildschirm gelöscht

/*Beginne mit der Datei zu arbeiten*/
ofstream out („C:\\\FromC\\myfile.txt“); //Öffnen einer Datei zum Schreiben
aus<
Schreiben Sie die erste Zeile auf
aus<Schreiben Sie die zweite Zeile
aus<Schreiben Sie die dritte Zeile auf
out.close(); // Schließen der Datei

//Variablen zurücksetzen

für (int i =0 ;i<=255 ;i ++)
(a =*““ ; b =*““ ; c=*““ ;)

/*Mit der Datei weiterarbeiten*/

wenn Stream in („C:\\\FromC\\meineDatei.txt“ );
in.getline(a,sizeof(a));// A
in.getline(b,sizeof(b));// Eine Zeile in eine Variable einlesen B
in.getline(c,sizeof(c)); // Eine Zeile in eine Variable einlesen C
in.close(); // Schließen der Datei

/* Wir lesen die erste Zeile Zeichen für Zeichen und zeigen sie auf dem Bildschirm an */

für (i =0 ;a !=*““ ;i++)
{
if (i >sizeof(a )) brechen ;
cout<

}
cout<<“\n” ; \\ Der Cursor wurde in eine neue Zeile verschoben

/* Wir lesen die zweite Zeile Zeichen für Zeichen und zeigen sie auf dem Bildschirm an */

für (i =0 ;b !=*““ ;i ++)
{
if (i >sizeof(b)) brechen ;
cout<
}
cout<<“\n” ; \\ Der Cursor wurde in eine neue Zeile verschoben

/* Wir lesen die dritte Zeile Zeichen für Zeichen und zeigen sie auf dem Bildschirm an */

für (i =0 ;с !=*““ ;i++)
{
if (i>sizeof (c )) brechen ;
cout<<с[i];
}

getch(); \\Warten auf das Drücken der Eingabetaste
return 0 ;
}
===================

Dieses Material beschreibt ein Beispiel für das zeichenweise Lesen von Informationen. Da ich die Arbeit mit Variablen wie z. B. nicht beschrieben habe verkohlen, dann kann es für Anfänger zu Unannehmlichkeiten beim Verständnis des Codes kommen. Ich wusste nur nicht, welcher Typ verkohlen hat einige Besonderheiten und dachte, alles wäre einfacher. Daher können einige unverständliche Momente des obigen Programms im folgenden Artikel nachgelesen werden Arbeiten mit Char V C++ für Anfänger

Ansonsten sollte das gegebene Beispiel zum Lesen von Zeilen aus einer Textdatei in C++ zugänglich und durchaus verständlich sein. Dies ist im Moment nicht die optimale Implementierungsoption und ich habe einige wichtige Punkte übersehen, aber da wir anfangen, die Sprache C++ zu lernen, reicht das für den Moment völlig aus. Später werde ich wahrscheinlich zu dem kommen, was ich verpasst habe, aber jetzt muss ich nur noch das Nötigste wahrnehmen.

Wenn Sie und ich dieses Material verstehen, bedeutet das, dass wir einen kleinen Schritt in Richtung unserer Professionalität gemacht haben.

Notiz:
brechen ;– Dies ist der Befehl, der die Schleife verlässt. Wir haben den Zykluszähler für wird größer als die deklarierte Größe der Variablen verkohlen, dann verlassen wir die Schleife gewaltsam
!= – Dies ist die Bedingung, die wir festgelegt haben. Dieser Zustand wird mit Ungleichung bezeichnet
if(a !=b )– Liest sich, als ob A nicht gleich B

endl ; – Dadurch wird der Cursor in eine neue Zeile innerhalb der Konsole bewegt (soweit ich weiß).
Dieser Befehl ähnelt "\N"

Bisher haben wir bei der Ein- und Ausgabe von Daten mit Standard-Streams gearbeitet – der Tastatur und dem Monitor. Schauen wir uns nun an, wie die Sprache C das Empfangen von Daten aus Dateien und das Schreiben dieser Daten in diese implementiert. Bevor Sie diese Vorgänge ausführen können, müssen Sie die Datei öffnen und darauf zugreifen.

In der Programmiersprache C ist ein Zeiger auf eine Datei vom Typ FILE und seine Deklaration sieht folgendermaßen aus:
DATEI *meineDatei;

Andererseits öffnet die Funktion fopen() eine Datei an der als erstes Argument angegebenen Adresse im Lesemodus („r“), Schreibmodus („w“) oder Anhängemodus („a“) und gibt einen Zeiger zurück dazu zum Programm. Daher sieht der Vorgang zum Öffnen einer Datei und zum Verbinden mit dem Programm in etwa so aus:
myfile = fopen("hello.txt", "r");

Beim Lesen oder Schreiben von Daten in eine Datei wird über einen Dateizeiger (in diesem Fall myfile) darauf zugegriffen.

Wenn die Funktion fopen() aus dem einen oder anderen Grund (es gibt keine Datei an der angegebenen Adresse, der Zugriff darauf ist verweigert) die Datei nicht öffnen kann, gibt sie NULL zurück. In realen Programmen behandeln sie fast immer einen Fehler beim Öffnen einer Datei im if-Zweig, wir werden dies jedoch weiter weglassen.

Die Funktionsdeklaration fopen() ist in der Header-Datei stdio.h enthalten und muss daher einbezogen werden. Auch in stdio.h ist der Strukturtyp FILE deklariert.

Nachdem die Arbeit mit einer Datei abgeschlossen ist, ist es üblich, sie zu schließen, um den Puffer von Daten zu befreien und aus anderen Gründen. Dies ist besonders wichtig, wenn das Programm nach der Arbeit mit der Datei weiterläuft. Das Unterbrechen der Verbindung zwischen einer externen Datei und einem Zeiger darauf vom Programm erfolgt mit der Funktion fclose(). Als Parameter wird ihr ein Zeiger auf die Datei übergeben:
fclose(meineDatei);

Im Programm können mehrere Dateien geöffnet werden. In diesem Fall muss jeder Datei ein eigener Dateizeiger zugeordnet werden. Wenn das Programm jedoch zunächst mit einer Datei arbeitet und diese dann schließt, kann der Zeiger zum Öffnen einer zweiten Datei verwendet werden.

Lesen aus und Schreiben in eine Textdatei

fscanf()

Die Funktion fscanf() hat eine ähnliche Bedeutung wie die Funktion scanf(), stellt jedoch im Gegensatz zu dieser eine formatierte Eingabe aus einer Datei anstelle einer Standardeingabe bereit. Die Funktion fscanf() benötigt Parameter: Dateizeiger, Formatzeichenfolge, Adressen von Speicherbereichen zum Schreiben von Daten:
fscanf(myfile, "%s%d", str, &a);

Gibt die Anzahl der erfolgreich gelesenen Daten oder EOF zurück. Leerzeichen und Zeilenumbrüche werden als Datentrennzeichen gezählt.

Nehmen wir an, wir haben eine Datei mit der folgenden Beschreibung von Objekten:

Äpfel 10 23,4 Bananen 5 25,0 Brot 1 10,3

#enthalten main () ( FILE * file; struct food ( char name[ 20 ] ; unsigned qty; float price; ); struct food shop[ 10 ] ; char i= 0 ; file = fopen ("fscanf.txt" , "r" ); while (fscanf (file, "%s%u%f" , shop[ i].name , & (shop[ i].qty ) , & (shop[ i].price ) ) != EOF) ( printf ("%s %u %.2f \N", shop[ i].name, shop[ i].qty, shop[ i].price); i++; ) )

In diesem Fall werden eine Struktur und ein Array von Strukturen deklariert. Jede Zeile aus der Datei entspricht einem Element des Arrays; Ein Array-Element ist eine Struktur, die eine Zeichenfolge und zwei numerische Felder enthält. Die Schleife liest eine Zeile pro Iteration. Wenn das Ende der Datei erreicht ist, gibt fscanf() EOF zurück und die Schleife endet.

fgets()

Die Funktion fgets() ähnelt der Funktion gets() und führt zeilenweise Eingaben aus einer Datei aus. Ein Aufruf von fgets() liest eine Zeile. In diesem Fall können Sie nicht die gesamte Zeile lesen, sondern nur einen Teil davon von Anfang an. fgets()-Parameter sehen so aus:
fgets (character_array, number_of_characters_read, pointer_to_file)

Zum Beispiel:
fgets(str, 50, myfile)

Dieser Funktionsaufruf liest aus der mit dem myfile-Zeiger verknüpften Datei eine vollständige Textzeile, wenn ihre Länge weniger als 50 Zeichen beträgt, einschließlich des Zeichens „\n“, das die Funktion ebenfalls in einem Array speichert. Das letzte (50.) Element des str-Arrays ist das von fgets() hinzugefügte Zeichen „\0“. Wenn die Zeichenfolge länger ist, liest die Funktion 49 Zeichen und schreibt am Ende „\0“. In diesem Fall ist „\n“ nicht in der Lesezeile enthalten.

#enthalten #define N 80 main () ( FILE * file; char arr[ N] ; file = fopen ("fscanf.txt" , "r" ) ; while (fgets (arr, N, file) != NULL) printf (" %s" , arr) ; printf (" \N"); fclose(Datei); )

In diesem Programm werden die Daten im Gegensatz zum vorherigen zeilenweise in das arr-Array eingelesen. Beim Lesen der nächsten Zeile geht die vorherige verloren. Die Funktion fgets() gibt NULL zurück, wenn sie die nächste Zeile nicht lesen kann.

getc() oder fgetc()

Mit der Funktion getc() oder fgetc() (beide funktionieren) können Sie das nächste einzelne Zeichen aus einer Datei abrufen.

while ((arr[ i] = fgetc (file) ) != EOF) ( if (arr[ i] == " \N") (arr[i] = " \0 " ; printf("%s \N", arr) ; ich = 0 ; ) sonst i++; )arr[i] = " \0 " ; printf("%s \N", arr) ;

Der Beispielcode zeigt Daten aus einer Datei auf dem Bildschirm an.

Schreiben in eine Textdatei

Genau wie die Eingabe kann auch die Ausgabe in eine Datei unterschiedlich sein.

  • Formatierte Ausgabe. Funktion fprintf (file_index, format_string, variables) .
  • Post-by-Line-Ausgabe. Funktion fputs(string, file_pointer) .
  • Zeichenweise Ausgabe. Funktion fputc() oder putc(symbol, file_pointer) .

Nachfolgend finden Sie Codebeispiele, die drei Methoden zum Ausgeben von Daten in eine Datei verwenden.

Felder einer Struktur in jede Zeile der Datei schreiben:

file = fopen ("fprintf.txt" , "w" ); while (scanf ("%s%u%f" , shop[ i].name , & (shop[ i].qty ) , & (shop[ i].price ) ) != EOF) ( fprintf (file, " %s %u %.2f \N", shop[ i].name, shop[ i].qty, shop[ i].price); i++; )

Zeilenweise Ausgabe in eine Datei (fputs() setzt im Gegensatz zu puts() selbst kein „\n“ am Ende der Zeile):

while (gets (arr) != NULL) ( fputs (arr, file); fputs (" \N", Datei); )

Beispiel für eine zeichenweise Ausgabe:

while ((i = getchar () ) != EOF) putc (i, file) ;

Lesen und Schreiben in eine Binärdatei

Sie können mit einer Datei nicht als Folge von Zeichen, sondern als Folge von Bytes arbeiten. Eine andere Arbeit mit Nicht-Textdateien ist prinzipiell nicht möglich. Sie können auf diese Weise jedoch Textdateien lesen und schreiben. Der Vorteil dieser Zugriffsmethode auf eine Datei liegt in der Lese-/Schreibgeschwindigkeit: Mit einem Zugriff kann ein erheblicher Informationsblock gelesen/geschrieben werden.

Beim Öffnen einer Datei für den Binärzugriff ist der zweite Parameter von fopen() die Zeichenfolge „rb“ oder „wb“.

Das Thema der Arbeit mit Binärdateien ist recht komplex und erfordert eine separate Lektion, um es zu studieren. Hier werden nur die Funktionen des Lesens und Schreibens in eine Datei, die als Bytestream betrachtet wird, erwähnt.

Die Funktionen fread() und fwrite() verwenden als Parameter:

  1. Adresse des Speicherbereichs, in den Daten geschrieben oder gelesen werden,
  2. die Größe eines gegebenen Typs,
  3. die gelesene Datenmenge der angegebenen Größe,
  4. Dateiindex.

Diese Funktionen geben die Anzahl der erfolgreich gelesenen oder geschriebenen Daten zurück. Diese. Sie können das Lesen von 50 Datenelementen „anordnen“, erhalten aber nur 10. Es wird kein Fehler angezeigt.

Ein Beispiel für die Verwendung der Funktionen fread() und fwrite():

#enthalten #enthalten main () ( FILE * file; char Shelf1[ 50 ], Shelf2[ 100 ] ; int n, m; file = fopen ("shelf1.txt" , "rb" ) ; n= fread (shelf1, sizeof (char ) , 50 , Datei) ; fclose (Datei) ; file = fopen ("shelf2.txt" , "rb" ); m= fread (shelf2, sizeof (char ) , 50 , Datei) ; fclose (Datei) ; Shelf1[ n] = " \0 " ; Shelf2[m] = " \N"; Shelf2[ m+ 1 ] = " \0 " ; file = fopen ("shop.txt" , "wb" ); fwrite (strcat (shelf2, Shelf1) , sizeof (char ) , n+ m, file) ; fclose(Datei); )

Hier wird versucht, 50 Zeichen aus der ersten Datei zu lesen. n speichert die Anzahl der tatsächlich gelesenen Zeichen. Der Wert von n kann 50 oder weniger betragen. Die Daten werden in einer Zeile platziert. Das Gleiche passiert mit der zweiten Datei. Als nächstes wird die erste Zeile an die zweite angehängt und die Daten werden in die dritte Datei übertragen.

Probleme lösen

  1. Schreiben Sie ein Programm, das den Benutzer nach dem Namen (Adresse) einer Textdatei fragt, diese dann öffnet und die Anzahl der darin enthaltenen Zeichen und Zeilen zählt.
  2. Schreiben Sie ein Programm, das Daten in eine Datei schreibt, die von einer anderen Datei empfangen und vor dem Schreiben auf irgendeine Weise geändert wurden. Jede aus einer Datei erhaltene Datenzeile muss in eine Struktur passen.

Die Funktion fopen() öffnet einen Stream zur Verwendung, ordnet diesem Stream eine Datei zu und gibt dann einen FILE-Zeiger auf diesen Stream zurück. Meistens wird die Datei als Festplattendatei behandelt. Die Funktion fopen() hat den folgenden Prototyp:

FILE *fopen(const char *filename, const char *mode);

Wobei mode auf eine Zeichenfolge verweist, die den gewünschten Modus zum Öffnen der Datei enthält. Gültige Werte für den Modus in Borland C++ sind in der Tabelle aufgeführt. Dateiname muss eine Zeichenfolge sein, die dem Betriebssystem einen gültigen Dateinamen bereitstellt, und kann einen Pfadnamen enthalten.

Die Funktion fopen() gibt einen Zeiger auf den Basistyp FILE zurück. Dieser Zeiger identifiziert die Datei und wird von den meisten Dateisystemfunktionen verwendet. Sie sollten es niemals selbst ändern. Die Funktion gibt einen Nullzeiger zurück, wenn die Datei nicht geöffnet werden kann.

Wie die Tabelle zeigt, kann die Datei entweder im Text- oder Binärmodus geöffnet werden. Im Textmodus wird während der Eingabe die Folge von Wagenrückläufen und Zeilenvorschüben in ein Zeilenumbruchzeichen übersetzt. Bei der Ausgabe ist das Gegenteil der Fall: Das Newline-Zeichen wird in einen Wagenrücklauf und einen Zeilenvorschub übersetzt. Diese Übersetzung findet in Binärdateien nicht statt. Wenn im Modusargument weder t noch b angegeben ist, wird der Text-/Binärstatus der Datei durch den Wert der in Borland C++ definierten globalen Variablen _fmode bestimmt. Standardmäßig ist fmode auf O_TEXT eingestellt, dh der Textmodus ist festgelegt. Wenn Sie _fmode auf O_BINARY setzen, werden Dateien im Binärmodus geöffnet. (Diese Makros sind in fcntl.h definiert.) Durch die Verwendung eines expliziten t oder b werden natürlich die mit der Variablen _fmode verbundenen Auswirkungen eliminiert. Darüber hinaus ist _fmode nur für Borland-Produkte spezifisch. Es ist im ANSI-C-I/O-System nicht definiert.

Wenn Sie eine Datei mit dem Namen test zum Schreiben öffnen müssen, sollten Sie Folgendes schreiben:

Fp = fopen("test", "w");

Wobei fp eine Variable vom Typ FILE * ist. Es ist jedoch üblich, Folgendes zu sehen:

If((fp = fopen("test", "w"))==NULL) (
puts("Datei kann nicht geöffnet werden.");
Ausgang(1);
}

Mit dieser Methode können Sie beim Öffnen einer Datei Fehler erkennen, beispielsweise das Vorhandensein eines Schreibschutzes oder einen Mangel an freiem Speicherplatz auf der Festplatte.

Wenn fopen() verwendet wird, um eine Datei zum Schreiben zu öffnen, werden alle bereits vorhandenen Dateien mit dem angegebenen Namen gelöscht. Wenn eine Datei mit dem angegebenen Namen nicht existiert, wird sie erstellt.

Wenn Sie Informationen an das Ende der Datei anhängen müssen, sollten Sie den Modus a (anhängen) verwenden. Wenn die Datei nicht existiert, wird sie erstellt.

Um eine Datei zum Lesen zu öffnen, muss die Datei vorhanden sein. Wenn die Datei nicht vorhanden ist, wird ein Fehler zurückgegeben. Wenn eine Datei für einen Lese-/Schreibvorgang geöffnet wird, wird sie nicht gelöscht, wenn sie existiert. Wenn die Datei nicht existiert, wird sie erstellt.

Tabelle: Zulässige Moduswerte

Bedeutung

Öffnet eine Datei zum Lesen. (Wird standardmäßig als Textdatei geöffnet.)

Erstellt eine Datei zum Schreiben. (Wird standardmäßig als Textdatei geöffnet.)

Wird an eine Datei angehängt. (Wird standardmäßig als Textdatei geöffnet.)

Öffnet eine Binärdatei zum Lesen.

Öffnet eine Binärdatei zum Schreiben.

Wird an eine Binärdatei angehängt.

Öffnet eine Datei zum Lesen/Schreiben. (Wird standardmäßig als Textdatei geöffnet.)

Erstellt eine Lese-/Schreibdatei. (Wird standardmäßig als Textdatei geöffnet.)

Hängt eine Lese-/Schreibdatei an oder erstellt sie. (Wird standardmäßig als Textdatei geöffnet.)

Öffnet eine Binärdatei zum Lesen/Schreiben.

Erstellt eine Binärdatei mit Lese-/Schreibzugriff.

Hängt eine Binärdatei mit Lese-/Schreibzugriff an oder erstellt sie.

Erstellt eine Textdatei zum Schreiben.

Wird an eine Textdatei angehängt.

Öffnet eine Textdatei zum Lesen.

Erstellt eine Textdatei zum Lesen/Schreiben.

Öffnet oder erstellt eine Textdatei zum Lesen/Schreiben.

Die meisten Computerprogramme arbeiten mit Dateien und daher besteht die Notwendigkeit, Dateien zu erstellen, zu löschen, zu schreiben, zu lesen und zu öffnen. Was ist eine Datei? Eine Datei ist eine benannte Menge von Bytes, die auf einem Speichergerät gespeichert werden kann. Nun ist klar, dass es sich bei einer Datei um eine bestimmte Folge von Bytes handelt, die einen eigenen, eindeutigen Namen hat, zum Beispiel file.txt. Dateien mit demselben Namen können nicht im selben Verzeichnis liegen. Der Dateiname bezieht sich nicht nur auf seinen Namen, sondern auch auf seine Erweiterung, zum Beispiel: file.txt und file.dat unterschiedliche Dateien, obwohl sie den gleichen Namen haben. Es gibt so etwas wie einen vollständigen Dateinamen – dies ist die vollständige Adresse des Dateiverzeichnisses, die den Dateinamen angibt, zum Beispiel: D:\docs\file.txt. Es ist wichtig, diese Grundkonzepte zu verstehen, sonst wird es schwierig, mit Dateien zu arbeiten.

Um mit Dateien arbeiten zu können, müssen Sie eine Header-Datei einschließen . IN Es sind mehrere Klassen definiert und Header-Dateien enthalten Dateieingabe und Dateiausgabe.

Datei-E/A ähnelt der Standard-E/A. Der einzige Unterschied besteht darin, dass die E/A in einer Datei und nicht auf dem Bildschirm ausgeführt wird. Wenn E/A an Standardgeräte mithilfe der Objekte cin und cout durchgeführt wird, reicht es zum Organisieren von Datei-E/A aus, eigene Objekte zu erstellen, die ähnlich wie die Operatoren cin und cout verwendet werden können.

Sie müssen beispielsweise eine Textdatei erstellen und die Zeile „Arbeiten mit Dateien in C++“ hineinschreiben. Dazu müssen Sie die folgenden Schritte ausführen:

  1. Erstellen Sie ein Objekt der Klasse ofstream ;
  2. Ordnen Sie der Datei, in die geschrieben werden soll, ein Klassenobjekt zu.
  3. eine Zeile in eine Datei schreiben;
  4. Schließen Sie die Datei.

Warum ist es notwendig, ein Ofstream-Objekt anstelle eines Ifstream-Objekts zu erstellen? Da Sie in eine Datei schreiben und Daten aus einer Datei lesen müssen, wird ein ifstream-Klassenobjekt erstellt.

// ein Objekt zum Schreiben in die Datei des Streams erstellen /*Objektname*/; // Objekt der Klasse ofstream

Nennen wir das Objekt fout. Das bekommen wir:

Ofstream fout;

Warum brauchen wir ein Objekt? Das Objekt wird benötigt, um in eine Datei schreiben zu können. Das Objekt wurde bereits erstellt, ist jedoch nicht mit der Datei verknüpft, in die die Zeichenfolge geschrieben werden muss.

Fout.open("cppstudio.txt"); // das Objekt mit der Datei verknüpfen

Durch die Punktoperation erhalten wir Zugriff auf die Klassenmethode open(), in der wir den Dateinamen in Klammern angeben. Die angegebene Datei wird mit dem Programm im aktuellen Verzeichnis erstellt. Wenn eine Datei mit demselben Namen vorhanden ist, wird die vorhandene Datei durch die neue ersetzt. Die Datei ist also geöffnet, es bleibt nur noch die erforderliche Zeile hineinzuschreiben. Das geht so:

Fout<< "Работа с файлами в С++"; // запись строки в файл

Mithilfe der Stream-Operation in Verbindung mit dem fout-Objekt wird die Zeichenfolge Arbeiten mit Dateien in C++ in eine Datei geschrieben. Da keine Notwendigkeit mehr besteht, den Inhalt der Datei zu ändern, muss diese geschlossen werden, d. h. das Objekt muss von der Datei getrennt werden.

Fout.close(); // schließe die Datei

Ergebnis: Es wurde eine Datei mit der Zeile „Arbeiten mit Dateien in C++“ erstellt.

Die Schritte 1 und 2 können kombiniert werden, d. h. in einer Zeile ein Objekt erstellen und es einer Datei zuordnen. Das geht so:

Ofstream fout("cppstudio.txt"); // ein Objekt der Klasse ofstream erstellen und es der Datei cppstudio.txt zuordnen

Lassen Sie uns den gesamten Code kombinieren und das folgende Programm erhalten.

// file.cpp: Definiert den Einstiegspunkt für die Konsolenanwendung. #include „stdafx.h“ #include Verwenden des Namensraums std; int main(int argc, char* argv) ( ofstream fout("cppstudio.txt"); // ein Objekt der Klasse ofstream für die Aufnahme erstellen und es mit der Datei cppstudio.txt verknüpfen fout<< "Работа с файлами в С++"; // запись строки в файл fout.close(); // закрываем файл system("pause"); return 0; }

Es bleibt zu überprüfen, ob das Programm ordnungsgemäß funktioniert, und öffnen Sie dazu die Datei cppstudio.txt und schauen Sie sich seinen Inhalt an, es sollte sein - Arbeiten mit Dateien in C++.

  1. Erstellen Sie ein Objekt der Klasse ifstream und verknüpfen Sie es mit der Datei, aus der gelesen werden soll.
  2. Datei lesen;
  3. Schließen Sie die Datei.
// file_read.cpp: Definiert den Einstiegspunkt für die Konsolenanwendung. #include „stdafx.h“ #include #enthalten Verwenden des Namensraums std; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // korrekte Anzeige des kyrillischen Zeichenbuffs; // Puffer für die Zwischenspeicherung des aus einer Datei gelesenen Textes ifstream fin("cppstudio.txt") ; // Datei zum Lesen geöffnet fin >><< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку system("pause"); return 0; }

Das Programm zeigt zwei Möglichkeiten zum Lesen aus einer Datei: Die erste ist die Verwendung der Übertragungsoperation in einen Stream, die zweite die Verwendung der Funktion getline() . Im ersten Fall wird nur das erste Wort gelesen, im zweiten Fall wird eine 50 Zeichen lange Zeichenfolge gelesen. Da die Datei jedoch weniger als 50 Zeichen enthält, werden die Zeichen bis einschließlich des letzten Zeichens gelesen. Bitte beachten Sie, dass beim zweiten Lesen (Zeile 17) wurde nach dem ersten Wort fortgesetzt und nicht von Anfang an, da das erste Wort eingelesen wurdeZeile 14. Das Ergebnis des Programms ist in Abbildung 1 dargestellt.

Arbeiten mit Dateien in C++ Um fortzufahren, drücken Sie eine beliebige Taste. . .

Abbildung 1 – Arbeiten mit Dateien in C++

Das Programm funktionierte korrekt, aber das passiert nicht immer, auch wenn mit dem Code alles in Ordnung ist. Beispielsweise wurde dem Programm der Name einer nicht vorhandenen Datei übergeben oder es liegt ein Fehler im Namen vor. Was dann? In diesem Fall wird überhaupt nichts passieren. Die Datei wird nicht gefunden und kann daher nicht gelesen werden. Daher ignoriert der Compiler Zeilen, in denen an der Datei gearbeitet wird. Dadurch wird das Programm ordnungsgemäß beendet, es wird jedoch nichts auf dem Bildschirm angezeigt. Es scheint, dass dies eine völlig normale Reaktion auf eine solche Situation ist. Ein einfacher Benutzer wird jedoch nicht verstehen, was vor sich geht und warum die Zeile aus der Datei nicht auf dem Bildschirm angezeigt wird. Um alles ganz klar zu machen: C++ bietet eine solche Funktion – is_open(), die ganzzahlige Werte zurückgibt: 1 – wenn die Datei erfolgreich geöffnet wurde, 0 – wenn die Datei nicht geöffnet wurde. Ändern wir das Programm mit dem Öffnen einer Datei so, dass eine entsprechende Meldung angezeigt wird, wenn die Datei nicht geöffnet ist.

// file_read.cpp: Definiert den Einstiegspunkt für die Konsolenanwendung. #include „stdafx.h“ #include #enthalten Verwenden des Namensraums std; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // korrekte Anzeige des kyrillischen Zeichenbuffs; // Puffer für die Zwischenspeicherung des aus einer Datei gelesenen Textes ifstream fin("cppstudio.doc") ; // (Sie haben einen ungültigen Dateinamen eingegeben) if (!fin.is_open()) // wenn die Datei nicht geöffnet ist cout<< "Файл не может быть открыт!\n"; // сообщить об этом else { fin >>buff; // zählte das erste Wort aus der Cout-Datei<< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку } system("pause"); return 0; }

Das Ergebnis des Programms ist in Abbildung 2 dargestellt.

Die Datei kann nicht geöffnet werden! Um fortzufahren, drücken Sie eine beliebige Taste. . .

Abbildung 2 – Arbeiten mit Dateien in C++

Wie aus Abbildung 2 hervorgeht, meldete das Programm, dass die Datei nicht geöffnet werden konnte. Wenn das Programm mit Dateien arbeitet, wird daher empfohlen, diese Funktion is_open() zu verwenden, auch wenn Sie sicher sind, dass die Datei existiert.

Modi zum Öffnen von Dateien

Dateiöffnungsmodi bestimmen, wie Dateien verwendet werden. Um den Modus festzulegen, stellt die Klasse ios_base Konstanten bereit, die den Dateiöffnungsmodus bestimmen (siehe Tabelle 1).

Dateiöffnungsmodi können direkt beim Erstellen eines Objekts oder beim Aufruf der Funktion open() festgelegt werden .

Ofstream fout("cppstudio.txt", ios_base::app); // öffne die Datei, um Informationen an das Ende der Datei anzuhängen fout.open("cppstudio.txt", ios_base::app); // Öffnen Sie die Datei, um Informationen an das Ende der Datei anzuhängen

Dateiöffnungsmodi können mithilfe einer bitweisen logischen Operation kombiniert werden oder| , zum Beispiel: ios_base::out | ios_base::trunc – öffnet eine Datei zum Schreiben, nachdem sie gelöscht wurde.

Objekte der ofstream-Klasse enthalten, wenn sie mit Dateien verknüpft sind, standardmäßig den Dateiöffnungsmodus ios_base::out | ios_base::trunc . Das heißt, die Datei wird erstellt, wenn sie nicht vorhanden ist. Wenn die Datei vorhanden ist, wird ihr Inhalt gelöscht und die Datei selbst ist zum Schreiben bereit. Objekte der ifstream-Klasse haben, wenn sie einer Datei zugeordnet sind, den Standard-Dateiöffnungsmodus ios_base::in – die Datei ist schreibgeschützt geöffnet. Der Dateiöffnungsmodus wird auch als Flag bezeichnet; aus Gründen der Lesbarkeit werden wir diesen Begriff in Zukunft verwenden. Tabelle 1 listet nicht alle Flags auf, diese sollten jedoch ausreichen, um Ihnen den Einstieg zu erleichtern.

Beachten Sie, dass die Flags „ate“ und „app“ in der Beschreibung sehr ähnlich sind. Beide verschieben den Zeiger an das Ende der Datei, das Flag „app“ erlaubt jedoch nur das Schreiben an das Ende der Datei und das Flag „ate“ verschiebt das Flag einfach an das Ende der Datei und schränkt den Schreibort nicht ein.

Lassen Sie uns ein Programm entwickeln, das mithilfe der Operation sizeof() die Eigenschaften der wichtigsten Datentypen in C++ berechnet und sie in eine Datei schreibt. Eigenschaften:

  1. Anzahl der für den Datentyp zugewiesenen Bytes
  2. der maximale Wert, den ein bestimmter Datentyp speichern kann.

Die Datei muss im folgenden Format geschrieben sein:

/* Datentyp Byte-Maximalwert bool = 1 255,00 char = 1 255,00 short int = 2 32767,00 unsigned short int = 2 65535,00 int = 4 2147483647,00 unsigned int = 4 4294967295,00 long int = 4 2147483647. 00 unsigned long int = 4 4294967295.00 float = 4 2147483647,00 Long Float = 8 9223372036854775800,00 Double = 8 9223372036854775800,00 */

Ein solches Programm wurde bereits weiter oben in diesem Abschnitt entwickelt, aber dort wurden alle Informationen über Datentypen auf dem Standardausgabegerät ausgegeben, und wir müssen das Programm neu erstellen, damit die Informationen in eine Datei geschrieben werden. Dazu müssen Sie die Datei im Schreibmodus öffnen, wobei die aktuellen Dateiinformationen vorab gekürzt werden ( Zeile 14). Sobald die Datei erstellt und erfolgreich geöffnet wurde (Zeilen 16–20), wird anstelle der cout-Anweisung in Zeile 22 Wir verwenden das fout-Objekt. somit werden statt des Bildschirms Informationen über die Datentypen in eine Datei geschrieben.

// write_file.cpp: Definiert den Einstiegspunkt für die Konsolenanwendung. #include „stdafx.h“ #include #enthalten // Mit Dateien arbeiten #include // Eingabe-/Ausgabemanipulatoren mit Namespace std; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // Ordnen Sie das Objekt der Datei zu und öffnen Sie die Datei im Schreibmodus, wobei Sie zunächst alle Daten daraus löschen ofstream fout("data_types.txt ", ios_base::out | ios_base::trunc); if (!fout.is_open()) // wenn die Datei nicht geöffnet wurde ( cout<< "Файл не может быть открыт или создан\n"; // напечатать соответствующее сообщение return 1; // выполнить выход из программы } fout << " data type " << "byte" << " " << " max value "<< endl // Spaltenüberschriften <<"bool = " << sizeof(bool) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных bool*/ << (pow(2,sizeof(bool) * 8.0) - 1) << endl << "char = " << sizeof(char) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных char*/ << (pow(2,sizeof(char) * 8.0) - 1) << endl << "short int = " << sizeof(short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных short int*/ << (pow(2,sizeof(short int) * 8.0 - 1) - 1) << endl << "unsigned short int = " << sizeof(unsigned short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned short int*/ << (pow(2,sizeof(unsigned short int) * 8.0) - 1) << endl << "int = " << sizeof(int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных int*/ << (pow(2,sizeof(int) * 8.0 - 1) - 1) << endl << "unsigned int = " << sizeof(unsigned int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned int*/ << (pow(2,sizeof(unsigned int) * 8.0) - 1) << endl << "long int = " << sizeof(long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long int*/ << (pow(2,sizeof(long int) * 8.0 - 1) - 1) << endl << "unsigned long int = " << sizeof(unsigned long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных undigned long int*/ << (pow(2,sizeof(unsigned long int) * 8.0) - 1) << endl << "float = " << sizeof(float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных float*/ << (pow(2,sizeof(float) * 8.0 - 1) - 1) << endl << "long float = " << sizeof(long float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long float*/ << (pow(2,sizeof(long float) * 8.0 - 1) - 1) << endl << "double = " << sizeof(double) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных double*/ << (pow(2,sizeof(double) * 8.0 - 1) - 1) << endl; fout.close(); // программа больше не использует файл, поэтому его нужно закрыть cout << "Данные успешно записаны в файл data_types.txt\n"; system("pause"); return 0; }

Es ist nicht zu übersehen, dass die Änderungen im Programm minimal sind, und das alles dank der Tatsache, dass Standard-Eingabe/Ausgabe und Datei-Eingabe/Ausgabe auf genau die gleiche Weise verwendet werden. Am Ende des Programms, umZeile 45Wir haben die Datei explizit geschlossen, obwohl dies nicht notwendig ist, aber als gute Programmierpraxis gilt. Es ist erwähnenswert, dass alle Funktionen und Manipulatoren, die zur Formatierung der Standardeingabe/-ausgabe verwendet werden, auch für die Dateieingabe/-ausgabe relevant sind. Daher sind bei der Anweisung keine Fehler aufgetreten cout wurde durch ein Objekt ersetzt fout.

Stichworte: Textdateien, fopen, fclose, feof, setbuf, setvbuf, fflush, fgetc, fprintf, fscanf, fgets, gepufferter Stream, ungepufferter Stream.

Arbeiten mit Textdateien

Die Arbeit mit einer Textdatei ähnelt der Arbeit mit der Konsole: Mit formatierten Eingabefunktionen speichern wir Daten in einer Datei, mit formatierten Ausgabefunktionen lesen wir Daten aus einer Datei. Es gibt viele Nuancen, die wir später betrachten werden. Die wichtigsten Operationen, die durchgeführt werden müssen, sind

  • 1. Öffnen Sie die Datei, damit darauf zugegriffen werden kann. Dementsprechend können Sie es zum Lesen, Schreiben, Lesen und Schreiben, Umschreiben oder Schreiben bis zum Ende der Datei usw. öffnen. Wenn Sie eine Datei öffnen, können auch eine Reihe von Fehlern auftreten – die Datei existiert möglicherweise nicht, es handelt sich möglicherweise um den falschen Dateityp, Sie haben möglicherweise keine Berechtigung zum Arbeiten mit der Datei usw. All dies muss berücksichtigt werden.
  • 2. Direktes Arbeiten mit der Datei – Schreiben und Lesen. Auch hier müssen wir bedenken, dass wir nicht mit Arbeitsspeicher arbeiten, sondern mit einem gepufferten Stream, der seine eigenen Besonderheiten hinzufügt.
  • 3. Schließen Sie die Datei. Da es sich bei der Datei um eine Ressource außerhalb des Programms handelt, bleibt sie, wenn sie nicht geschlossen wird, weiterhin im Speicher hängen, möglicherweise auch nach dem Schließen des Programms (z. B. ist es nicht möglich, eine geöffnete Datei zu löschen oder Änderungen vorzunehmen). usw.). Darüber hinaus ist es manchmal notwendig, eine Datei nicht zu schließen, sondern „erneut zu öffnen“, um beispielsweise den Zugriffsmodus zu ändern.

Darüber hinaus gibt es eine Reihe von Aufgaben, bei denen wir nicht auf den Inhalt der Datei zugreifen müssen: Umbenennen, Verschieben, Kopieren usw. Leider enthält der C-Standard keine Beschreibung von Funktionen für diese Anforderungen. Sie sind natürlich für jede Compiler-Implementierung verfügbar. Das Lesen des Inhalts eines Verzeichnisses (Ordner, Verzeichnis) ist auch ein Zugriff auf eine Datei, da der Ordner selbst eine Datei mit Metainformationen ist.

Manchmal ist es notwendig, einige Hilfsoperationen durchzuführen: an die gewünschte Stelle in der Datei verschieben, sich die aktuelle Position merken, die Länge der Datei bestimmen usw.

Um mit einer Datei arbeiten zu können, benötigen Sie ein FILE-Objekt. Dieses Objekt speichert die Kennung des Dateistreams und die zu seiner Verwaltung erforderlichen Informationen, einschließlich eines Zeigers auf seinen Puffer, einer Dateipositionsanzeige und Statusanzeigen.

Das FILE-Objekt ist selbst eine Struktur, auf seine Felder sollte jedoch nicht zugegriffen werden. Das portable Programm muss die Datei als abstraktes Objekt behandeln, das den Zugriff auf den Dateistream ermöglicht.

Die Erstellung und Zuweisung von Speicher für ein Objekt vom Typ FILE erfolgt mit der Funktion fopen oder tmpfile (es gibt noch andere, aber wir konzentrieren uns nur auf diese).

Die Funktion fopen öffnet eine Datei. Es erhält zwei Argumente – einen String mit der Dateiadresse und einen String mit dem Dateizugriffsmodus. Der Dateiname kann entweder absolut oder relativ sein. fopen gibt einen Zeiger auf ein FILE-Objekt zurück, das für den weiteren Zugriff auf die Datei verwendet werden kann.

FILE* fopen(const char* Dateiname, const char* Modus);

Öffnen wir beispielsweise eine Datei und schreiben „Hello World“ hinein

#enthalten #enthalten #enthalten void main() ( //Mithilfe der Dateivariablen greifen wir auf die Datei FILE *file; //Öffnen Sie eine Textdatei mit Schreibberechtigungen file = fopen("C:/c/test.txt", "w+t") ; //Schreibe in die Datei fprintf(file, "Hello, World!"); //Schließe die Datei fclose(file); getch(); )

Die fopen-Funktion selbst reserviert Speicher für das Objekt; die Reinigung erfolgt durch die fclose-Funktion. Die Datei muss geschlossen werden; sie wird nicht von selbst geschlossen.

Die Funktion fopen kann eine Datei im Text- oder Binärmodus öffnen. Der Standardwert ist Text. Der Zugriffsmodus kann wie folgt sein

Dateizugriffsoptionen.
Typ Beschreibung
R Lektüre. Die Datei muss vorhanden sein.
w Schreiben Sie eine neue Datei. Wenn bereits eine Datei mit demselben Namen vorhanden ist, geht ihr Inhalt verloren.
A Schreiben Sie bis zum Ende der Datei. Positionierungsoperationen (fseek, fsetpos, frewind) werden ignoriert. Die Datei wird erstellt, wenn sie nicht existiert.
r+ Lesen und Aktualisieren. Sie können sowohl lesen als auch schreiben. Die Datei muss vorhanden sein.
w+ Aufzeichnung und Aktualisierung. Eine neue Datei wird erstellt. Wenn bereits eine Datei mit demselben Namen vorhanden ist, geht ihr Inhalt verloren. Sie können sowohl schreiben als auch lesen.
a+ Beitrag beenden und aktualisieren. Positionierungsvorgänge sind schreibgeschützt und werden bei Schreibvorgängen ignoriert. Wenn die Datei nicht vorhanden war, wird eine neue erstellt.

Wenn es notwendig ist, die Datei im Binärmodus zu öffnen, wird der Buchstabe b am Ende der Zeile hinzugefügt, zum Beispiel „rb“, „wb“, „ab“ oder für den gemischten Modus „ab+“, „ wb+“, „ab+“. Anstelle von b können Sie den Buchstaben t hinzufügen, dann wird die Datei im Textmodus geöffnet. Es kommt auf die Umsetzung an. Im neuen C-Standard (2011) bedeutet der Buchstabe x, dass fopen fehlschlagen sollte, wenn die Datei bereits existiert. Ergänzen wir unser altes Programm: Öffnen Sie die Datei erneut und überlegen Sie, was wir dort geschrieben haben.

#enthalten #enthalten #enthalten void main() ( FILE *file; char buffer; file = fopen("C:/c/test.txt", "w"); fprintf(file, "Hello, World!"); fclose(file); file = fopen("C:/c/test.txt", "r"); fgets(buffer, 127, file); printf("%s", buffer); fclose(file); getch(); )

Anstelle der fgets-Funktion könnten Sie auch fscanf verwenden, Sie müssen jedoch bedenken, dass damit nur die Zeile bis zum ersten Leerzeichen gelesen werden kann.
fscanf(file, „%127s“, buffer);

Anstatt eine Datei zu öffnen und zu schließen, können Sie auch die Funktion freopen verwenden, die die Datei mit neuen Zugriffsrechten „erneut öffnet“.

#enthalten #enthalten #enthalten void main() ( FILE *file; char buffer; file = fopen("C:/c/test.txt", "w"); fprintf(file, "Hello, World!"); freopen("C:/ c/test.txt", "r", file); fgets(buffer, 127, file); printf("%s", buffer); fclose(file); getch(); )

Die Funktionen fprintf und fscanf unterscheiden sich von printf und scanf nur dadurch, dass sie als erstes Argument einen Zeiger auf die DATEI verwenden, in die sie Daten ausgeben oder aus der sie Daten lesen. Es lohnt sich gleich hinzuzufügen, dass die Funktionen printf und scanf leicht durch die Funktionen fprintf und fscanf ersetzt werden können. Im Betriebssystem (wir betrachten die gängigsten und geeignetsten Betriebssysteme) gibt es drei Standardstreams: den Standardausgabestream stdout, den Standardeingabestream stdin und den Standardfehlerausgabestream stderr. Sie werden beim Start der Anwendung automatisch geöffnet und mit der Konsole verknüpft. Beispiel

#enthalten #enthalten #enthalten void main() ( int a, b; fprintf(stdout, "Geben Sie zwei Zahlen ein\n"); fscanf(stdin, "%d", &a); fscanf(stdin, "%d", &b); if (b == 0) ( fprintf(stderr, "Fehler: Division durch Null"); ) else ( fprintf(stdout, "%.3f", (float) a / (float) b); ) getch(); )

Fehler beim Öffnen der Datei

Wenn der Aufruf der fopen-Funktion fehlschlägt, wird NULL zurückgegeben. Bei der Arbeit mit Dateien treten häufig Fehler auf. Deshalb müssen wir jedes Mal, wenn wir eine Datei öffnen, das Ergebnis der Arbeit überprüfen

#enthalten #enthalten #enthalten #define ERROR_OPEN_FILE -3 void main() ( FILE *file; char buffer; file = fopen("C:/c/test.txt", "w"); if (file == NULL) ( printf("Fehler beim Öffnen file"); getch(); exit(ERROR_OPEN_FILE); ) fprintf(file, "Hello, World!"); freopen("C:/c/test.txt", "r", file); if (file = = NULL) ( printf("Fehler beim Öffnen der Datei"); getch(); exit(ERROR_OPEN_FILE); ) fgets(buffer, 127, file); printf("%s", buffer); fclose(file); getch() ; )

Das Problem entsteht, wenn mehrere Dateien gleichzeitig geöffnet werden: Wenn eine davon nicht geöffnet werden kann, müssen auch die anderen geschlossen werden

DATEI *Eingabedatei, *Ausgabedatei; vorzeichenloses m, n; ohne Vorzeichen i, j; inputFile = fopen(INPUT_FILE, READ_ONLY); if (inputFile == NULL) ( printf("Fehler beim Öffnen der Datei %s", INPUT_FILE); getch(); exit(3); ) outputFile = fopen(OUTPUT_FILE, WRITE_ONLY); if (outputFile == NULL) ( printf("Fehler beim Öffnen der Datei %s", OUTPUT_FILE); getch(); if (inputFile != NULL) ( fclose(inputFile); ) exit(4); ) ...

In einfachen Fällen können Sie direkt vorgehen, wie im vorherigen Codeabschnitt. In komplexeren Fällen werden Methoden verwendet, die RAII aus C++ ersetzen: Wrapper oder Compiler-Funktionen (Bereinigung in GCC) usw.

Datenpufferung

Wie bereits erwähnt, werden Daten bei der Ausgabe zunächst in einem Puffer abgelegt. Der Puffer wird gelöscht

  • 1) Wenn es voll ist
  • 2) Wenn der Stream geschlossen ist
  • 3) Wenn wir ausdrücklich darauf hinweisen, dass es notwendig ist, den Puffer zu löschen (auch hier gibt es Ausnahmen :)).
  • 4) Wird auch gelöscht, wenn das Programm erfolgreich abgeschlossen wurde. Gleichzeitig werden alle Dateien geschlossen. Im Falle eines Laufzeitfehlers kann dies nicht passieren.

Sie können das Entladen des Puffers erzwingen, indem Sie die Funktion fflush(File *) aufrufen. Schauen wir uns zwei Beispiele an – mit und ohne Reinigung.

#enthalten #enthalten #enthalten void main() ( FILE *file; char c; file = fopen("C:/c/test.txt", "w"); do ( c = getch(); fprintf(file, "%c", c ); fprintf(stdout, "%c", c); //fflush(file); ) while(c != "q"); fclose(file); getch(); )

Kommentieren Sie den Flush-Anruf aus. Öffnen Sie zur Laufzeit die Textdatei und sehen Sie sich das Verhalten an.

Sie können einen Dateipuffer selbst zuweisen, indem Sie Ihre eigene Größe festlegen. Dies geschieht über die Funktion

Void setbuf(FILE * stream, char * buffer);

Dies erfordert eine bereits geöffnete DATEI und einen Zeiger auf einen neuen Puffer. Die Größe des neuen Puffers darf nicht kleiner als BUFSIZ sein (auf der aktuellen Arbeitsstation beträgt BUFSIZ beispielsweise 512 Byte). Wenn Sie NULL als Puffer übergeben, wird der Stream ungepuffert. Sie können die Funktion auch nutzen

Int setvbuf(FILE * stream, char * buffer, int mode, size_t size);

die einen Puffer beliebiger Größe akzeptiert. Der Modus kann die folgenden Werte annehmen

  • _IOFBF- Vollständige Pufferung. Daten werden in die Datei geschrieben, wenn diese voll ist. Beim Lesen gilt der Puffer als voll, wenn eine Eingabeoperation angefordert wird und der Puffer leer ist.
  • _IOLBF- lineare Pufferung. Daten werden in die Datei geschrieben, wenn sie voll ist oder wenn ein Zeilenumbruchzeichen auftritt. Beim Lesen wird der Puffer bis zum Zeilenumbruchzeichen gefüllt, wenn eine Eingabeoperation angefordert wird und der Puffer leer ist.
  • _IONBF– keine Pufferung. In diesem Fall werden die Parameter Größe und Puffer ignoriert.
Bei Erfolg gibt die Funktion 0 zurück.

Beispiel: Lassen Sie uns unseren eigenen Puffer festlegen und sehen, wie das Lesen aus einer Datei erfolgt. Lassen Sie die Datei kurz sein (so etwas wie Hello, World!), und wir lesen sie Zeichen für Zeichen

#enthalten #enthalten #enthalten void main() ( FILE *input = NULL; char c; char buffer = (0); input = fopen("D:/c/text.txt", "rt"); setbuf(input, buffer); while ( !feof(input)) ( c = fgetc(input); printf("%c\n", c); printf("%s\n", buffer); _getch(); ) fclose(input); )

Es ist ersichtlich, dass sich die Daten bereits im Puffer befinden. Das Lesen Zeichen für Zeichen erfolgt aus dem Puffer.

feof

Funktion int feof(FILE * stream); gibt true zurück, wenn das Ende der Datei erreicht ist. Die Funktion ist praktisch, wenn Sie die gesamte Datei von Anfang bis Ende durchgehen müssen. Es sei eine Datei mit Textinhalt text.txt vorhanden. Wir lesen die Datei Zeichen für Zeichen und zeigen sie auf dem Bildschirm an.

#enthalten #enthalten #enthalten void main() ( FILE *input = NULL; char c; input = fopen("D:/c/text.txt", "rt"); if (input == NULL) ( printf("Fehler beim Öffnen der Datei") ; _getch(); exit(0); ) while (!feof(input)) ( c = fgetc(input); fprintf(stdout, "%c", c); ) fclose(input); _getch(); )

Alles wäre in Ordnung, aber die feof-Funktion funktioniert nicht richtig... Dies liegt daran, dass das Konzept des „Ende der Datei“ nicht definiert ist. Ein Fehler, der bei der Verwendung von feof häufig auftritt, besteht darin, dass die zuletzt gelesenen Daten zweimal gedruckt werden. Dies liegt daran, dass die Daten in den Eingabepuffer geschrieben werden, der letzte Lesevorgang mit einem Fehler erfolgt und die Funktion den alten gelesenen Wert zurückgibt.

#enthalten #enthalten #enthalten void main() ( FILE *input = NULL; char c; input = fopen("D:/c/text.txt", "rt"); if (input == NULL) ( printf("Fehler beim Öffnen der Datei") ; _getch(); exit(0); ) while (!feof(input)) ( fscanf(input, "%c", &c); fprintf(stdout, "%c", c); ) fclose(input); _getch(); )

Dieses Beispiel wird (höchstwahrscheinlich) fehlschlagen und das letzte Zeichen der Datei zweimal drucken.

Die Lösung besteht darin, feof nicht zu verwenden. Speichern Sie beispielsweise die Gesamtzahl der Datensätze oder nutzen Sie die Tatsache, dass Funktionen von fscanf usw. normalerweise die Anzahl der korrekt gelesenen und abgeglichenen Werte zurückgeben.

#enthalten #enthalten #enthalten void main() ( FILE *input = NULL; char c; input = fopen("D:/c/text.txt", "rt"); if (input == NULL) ( printf("Fehler beim Öffnen der Datei") ; _getch(); exit(0); ) while (fscanf(input, "%c", &c) == 1) ( fprintf(stdout, "%c", c); ) fclose(input); _getch() ; )

Beispiele

1. Eine Datei enthält zwei Zahlen – die Abmessungen des Arrays. Füllen wir die zweite Datei mit einem Array von Zufallszahlen.

#enthalten #enthalten #enthalten #enthalten //Dateinamen und Berechtigungen #define INPUT_FILE "D:/c/input.txt" #define OUTPUT_FILE "D:/c/output.txt" #define READ_ONLY "r" #define WRITE_ONLY "w" //Maximalwert für Array size #define MAX_DIMENSION 100 //Fehler beim Öffnen der Datei #define ERROR_OPEN_FILE -3 void main() ( FILE *inputFile, *outputFile; unsigned m, n; unsigned i, j; inputFile = fopen(INPUT_FILE, READ_ONLY); if ( inputFile == NULL) ( printf("Fehler beim Öffnen der Datei %s", INPUT_FILE); getch(); exit(ERROR_OPEN_FILE); ) OutputFile = fopen(OUTPUT_FILE, WRITE_ONLY); if (outputFile == NULL) ( printf("Fehler Datei %s öffnen", OUTPUT_FILE); getch(); //Wenn die Datei zum Lesen geöffnet werden konnte, muss sie geschlossen werden if (inputFile != NULL) ( fclose(inputFile); ) exit(ERROR_OPEN_FILE); ) fscanf (inputFile, "%ud %ud", &m, &n); if (m > MAX_DIMENSION) ( m = MAX_DIMENSION; ) if (n > MAX_DIMENSION) ( n = MAX_DIMENSION; ) srand(time(NULL)); für (i = 0; ich< n; i++) { for (j = 0; j < m; j++) { fprintf(outputFile, "%8d ", rand()); } fprintf(outputFile, "\n"); } //Закрываем файлы fclose(inputFile); fclose(outputFile); }

2. Der Benutzer kopiert die Datei und wählt zunächst den Betriebsmodus aus: Die Datei kann entweder auf der Konsole ausgegeben oder in eine neue Datei kopiert werden.

#enthalten #enthalten #enthalten #define ERROR_FILE_OPEN -3 void main() ( FILE *origin = NULL; FILE *output = NULL; char filename; int mode; printf("Enter filename: "); scanf("%1023s", filename); origin = fopen (filename, "r"); if (origin == NULL) ( printf("Fehler beim Öffnen der Datei %s", Dateiname); getch(); exit(ERROR_FILE_OPEN); ) printf("enter mode: "); scanf( "%d", &mode); if (mode == 1) ( printf("Enter filename: "); scanf("%1023s", filename); output = fopen(filename, "w"); if (output = = NULL) ( printf("Fehler beim Öffnen der Datei %s", Dateiname); getch(); fclose(origin); exit(ERROR_FILE_OPEN); ) ) else ( Output = stdout; ) while (!feof(origin)) ( fprintf (output, "%c", fgetc(origin)); ) fclose(origin); fclose(output); getch(); )

3. Der Benutzer gibt Daten über die Konsole ein und diese werden in eine Datei geschrieben, bis die Esc-Taste gedrückt wird. Schauen Sie sich das Programm an und sehen Sie. wie es sich verhält, wenn Sie die Rücktaste eingeben: Was wird in die Datei ausgegeben und was wird auf der Konsole ausgegeben.

#enthalten #enthalten #enthalten #define ERROR_FILE_OPEN -3 void main() ( FILE *output = NULL; char c; Output = fopen("D:/c/test_output.txt", "w+t"); if (output == NULL) ( printf ("Fehler beim Öffnen der Datei"); _getch(); exit(ERROR_FILE_OPEN); ) for (;;) ( c = _getch(); if (c == 27) ( break; ) fputc(c, Output); fputc( c, stdout); ) fclose(output); )

4. Die Datei enthält ganze Zahlen. Finden Sie das Maximum davon. Machen wir uns die Tatsache zunutze, dass die Funktion fscanf die Anzahl der korrekt gelesenen und übereinstimmenden Objekte zurückgibt. Die Nummer 1 sollte jedes Mal zurückgegeben werden.

#enthalten #enthalten #enthalten #define ERROR_FILE_OPEN -3 void main() ( FILE *input = NULL; int num, maxn, hasRead; input = fopen("D:/c/input.txt", "r"); if (input == NULL) ( printf("Fehler beim Öffnen der Datei"); _getch(); exit(ERROR_FILE_OPEN); ) maxn = INT_MIN; hasRead = 1; while (hasRead == 1) ( hasRead = fscanf(input, "%d", &num); if (hasRead != 1) ( continue; ) if (num >

Eine andere Lösung besteht darin, Zahlen zu lesen, bis wir das Ende der Datei erreichen.

#enthalten #enthalten #enthalten #enthalten #define ERROR_FILE_OPEN -3 void main() ( FILE *input = NULL; int num, maxn, hasRead; input = fopen("D:/c/input.txt", "r"); if (input == NULL) ( printf("Fehler beim Öffnen der Datei"); _getch(); exit(ERROR_FILE_OPEN); ) maxn = INT_MIN; while (!feof(input)) ( fscanf(input, "%d", &num); if (num > maxn ) ( maxn = num; ) ) printf("max number = %d", maxn); fclose(input); _getch(); )

5. Die Datei enthält Wörter: russisches Wort, Tabellierung, englisches Wort, in mehreren Zeilen. Der Benutzer gibt ein englisches Wort ein, das russische muss ausgegeben werden.

Die Übersetzungsdatei sieht in etwa so aus

Sonne Sonne
Bleistift
Kugelschreiber Bleistift
Tür Tür
Fensterfenster
Stuhl Stuhl
Sessel

und in cp866-Kodierung (OEM 866) gespeichert. Wichtig: Auch das letzte Wortpaar endet mit einem Zeilenvorschub.

Der Algorithmus ist wie folgt: Wir lesen eine Zeile aus einer Datei, suchen ein Tabulatorzeichen in der Zeile, ersetzen das Tabulatorzeichen durch eine Null, kopieren ein russisches Wort aus dem Puffer, kopieren ein englisches Wort aus dem Puffer und prüfen die Gleichheit.

#enthalten #enthalten #enthalten #enthalten #define ERROR_FILE_OPEN -3 void main() ( FILE *input = NULL; char buffer; char enWord; char ruWord; char usrWord; unsigned index; int length; int wasFound; input = fopen("D:/c/input.txt ", "r"); if (input == NULL) ( printf("Fehler beim Öffnen der Datei"); _getch(); exit(ERROR_FILE_OPEN); ) printf("Wort eingeben: "); fgets(usrWord, 127, stdin ); wasFound = 0; while (!feof(input)) ( fgets(buffer, 511, input); length = strlen(buffer); for (index = 0; index< length; index++) { if (buffer == "\t") { buffer = "\0"; break; } } strcpy(ruWord, buffer); strcpy(enWord, &buffer); if (!strcmp(enWord, usrWord)) { wasFound = 1; break; } } if (wasFound) { printf("%s", ruWord); } else { printf("Word not found"); } fclose(input); _getch(); }

6. Zählen Sie die Anzahl der Zeilen in der Datei. Wir lesen die Datei Zeichen für Zeichen und zählen die Anzahl der „\n“ Zeichen, bis wir auf das EOF-Zeichen stoßen. EOF ist ein Sonderzeichen, das anzeigt, dass die Eingabe abgeschlossen ist und keine Daten mehr gelesen werden müssen. Im Fehlerfall gibt die Funktion einen negativen Wert zurück.
HINWEIS: EOF ist vom Typ int, daher müssen Sie int verwenden, um die Zeichen zu lesen. Darüber hinaus ist der Wert von EOF nicht im Standard definiert.

#define _CRT_SECURE_NO_WARNINGS #include #enthalten #enthalten int cntLines(const char *filename) ( intlines = 0; int any; //any ist vom Typ int, weil EOF vom Typ int ist! FILE *f = fopen(filename, "r"); if (f == NULL ) ( return -1; ) do ( any = fgetc(f); //printf("%c", any);//debug if (any == "\n") (lines++; ) ) while(any ! = EOF); ​​​​fclose(f); returnlines; ) void main() ( printf("%d\n", cntLines("C:/c/file.txt")); _getch(); )

Ru-Cyrl 18-Tutorial Sypachev S.S. 14.04.1989 [email protected] Stepan Sypachev Studenten

Immer noch nicht klar? – Schreiben Sie Fragen an die Mailbox