So lesen Sie ein Zeichen aus Datei c. Eingabe aus Datei und Ausgabe in Datei

Arbeiten mit Textdateien in C++.

Es gibt zwei Haupttypen von Dateien: Text und Binärdateien. Mithilfe von Dateien kann der Benutzer große Datenmengen direkt von der Festplatte lesen, ohne sie über die Tastatur eingeben zu müssen.

    Text Es werden Dateien aufgerufen, die aus beliebigen Zeichen bestehen. Sie sind in Zeilen organisiert, die jeweils mit einem Zeilenendezeichen enden. Das Ende der Datei selbst wird durch das „Dateiende“-Symbol angezeigt. Beim Schreiben von Informationen in eine Textdatei, die mit jedem Texteditor angezeigt werden kann, werden alle Daten in einen Zeichentyp umgewandelt und in Zeichenform gespeichert.

    IN binär In Dateien werden Informationen in Form von Blöcken einer bestimmten Größe gelesen und geschrieben, in denen Daten beliebiger Art und Struktur gespeichert werden können.

Um mit Dateien zu arbeiten, ist etwas Besonderes Datentypen, angerufen Ströme. Fließen ifstream wird verwendet, um mit Dateien im Lesemodus zu arbeiten, und ofstream im Aufnahmemodus. Um mit Dateien sowohl im Schreib- als auch im Lesemodus zu arbeiten, wird ein Stream verwendet fstream.

Wenn Sie in C++-Programmen mit Textdateien arbeiten, müssen Sie die Bibliotheken iostream und fstream einbinden.

Damit aufschreiben Um Daten in eine Textdatei zu übertragen, benötigen Sie:

    Beschreiben Sie eine Variable vom Typ ofstream.

    Informationen in eine Datei ausgeben.

    Achten Sie darauf, die Datei zu schließen.

Für Lektüre Daten aus einer Textdatei benötigen Sie:

    Beschreiben Sie eine Variable vom Typ ifstream.

    Öffnen Sie eine Datei mit der Funktion „Öffnen“.

    Schließen Sie die Datei.

Aufzeichnen Informationen in eine Textdatei

    Wie bereits erwähnt, um mit der Arbeit zu beginnen Textdatei, ist es notwendig, eine Variable vom Typ Stream zu beschreiben. Zum Beispiel so:

    Es wird eine Variable F erstellt, um Informationen in die Datei zu schreiben.

    Im nächsten Schritt muss die Datei zum Schreiben geöffnet werden. Im Allgemeinen sieht der Stream-Öffnungsoperator so aus:

F.open("file", mode);

Hier ist F eine Variable, die als ofstream beschrieben wird,

Datei - Vollständiger Name Datei auf der Festplatte

Modus – Arbeitsmodus mit der geöffneten Datei.

Bitte beachten Sie, dass Sie bei der Angabe des vollständigen Dateinamens einen doppelten Schrägstrich verwenden müssen. Der vollständige Name der Datei noobs.txt, die sich im Spielordner auf Laufwerk D: befindet, muss beispielsweise wie folgt geschrieben werden:

D:\\game\\noobs.txt.

Die Datei kann in einem der folgenden Modi geöffnet werden:

ios::in – Öffnen Sie die Datei im Datenlesemodus. Dieser Modus ist der Standardmodus für ifstreams.

ios::out – öffnet eine Datei im Datenschreibmodus (in diesem Fall werden Informationen über die vorhandene Datei zerstört). Dieser Modus ist der Standardmodus für ofstreams;

ios::app – Öffnen Sie die Datei im Modus zum Schreiben von Daten bis zum Ende der Datei.

ios::ate – zum Ende einer bereits geöffneten Datei wechseln;

ios::trunc – Datei löschen, dies geschieht auch im ios::out-Modus;

ios::nocreate – eine Datei nicht öffnen, wenn sie nicht existiert;

ios::noreplace – keine vorhandene Datei öffnen.

Der Modusparameter kann fehlen. In diesem Fall wird die Datei im Standardmodus für diesen Stream geöffnet.

Nach erfolgreichem Öffnen der Datei (in jedem Modus) speichert die Variable F „true“, andernfalls „false“. Dadurch können Sie die Richtigkeit des Dateiöffnungsvorgangs überprüfen.

Sie können eine Datei (nehmen wir als Beispiel die Datei D:\\game\\noobs.txt) im Aufnahmemodus auf eine der folgenden Arten öffnen:

// Erste Weg

ofstream F;

F.open("D:\\game\\noobs.txt", ios::out);

//zweite Methode, ios::out-Modus ist der Standardmodus

// Für fließenofstream

ofstream F;

//Die dritte Methode kombiniert die Beschreibung der Variablen und des Stream-Typs

//und die Datei in einer Anweisung öffnen

ofstream F("D:\\game\\noobs.txt", ios::out);

Nach dem Öffnen der Datei im Schreibmodus wird eine leere Datei erstellt, in die Sie Informationen schreiben können.

Wenn Sie eine vorhandene Datei im Write-First-Modus öffnen möchten, sollten Sie ios::app als Modus verwenden.

Nachdem Sie eine Datei im Aufnahmemodus geöffnet haben, können Sie auf die gleiche Weise wie auf den Bildschirm schreiben, nur anstelle des StandardausgabegerätscoutSie müssen den Namen der geöffneten Datei angeben.

Um beispielsweise die Variable a in Stream F zu schreiben, sieht die Ausgabeanweisung wie folgt aus:

Für die sequentielle Ausgabe der Variablen b, c, d an Stream G sieht der Ausgabeoperator wie folgt aus:

G<

Das Schließen eines Streams erfolgt mit dem Operator:

BEISPIEL:

Erstellen Sie eine Textdatei D:\\game\\noobs.txt und schreiben Sie n reelle Zahlen hinein.

#include „stdafx.h“

#enthalten

#enthalten

#enthalten

Verwenden des Namensraums std;

int main()

setlocale(LC_ALL, "RUS");

int i, n;

Doppel a;

//beschreibt einen Stream zum Schreiben von Daten in eine Datei

ofstream F;

//öffne die Datei im Schreibmodus,

//Modusios:: ausstandardmäßig installiert

f.open("D:\\game\\noobs.txt", ios::out);

//Geben Sie die Anzahl der reellen Zahlen ein

cout<<" N="; cin>> N;

//Schleife zur Eingabe reeller Zahlen

//und schreibe sie in eine Datei

für (i=0; i

cout<<"a=";

//Geben Sie eine Zahl ein

cin>>a;

F<

//Den Stream schließen

f.close();

system("pause");

0 zurückgeben;

_______________________________________________________________

Um Informationen aus einer Textdatei zu lesen, müssen Sie eine Variable wie beschreiben ifstream. Anschließend müssen Sie die Datei mit dem Operator zum Lesen öffnen offen. Wenn die Variable F heißt, sehen die ersten beiden Anweisungen wie folgt aus:

F.open("D:\\game\\noobs.txt", ios::in);

Nachdem Sie eine Datei im Lesemodus geöffnet haben, können Sie Informationen daraus auf die gleiche Weise wie über die Tastatur lesen, nur stattcinGeben Sie den Namen des Streams an, aus dem Daten gelesen werden.

Um beispielsweise aus Stream F in die Variable a zu lesen, würde die Eingabeanweisung so aussehen:

Zwei Zahlen in einem Texteditor gelten als getrennt, wenn zwischen ihnen mindestens eines der folgenden Zeichen steht: Leerzeichen, Tabulator, Zeilenende. Es ist gut, wenn der Programmierer im Voraus weiß, wie viele und welche Werte er in der Textdatei speichern soll. Allerdings ist die Art der in der Datei gespeicherten Werte oft einfach bekannt, ihre Anzahl kann jedoch variieren. Um dieses Problem zu lösen, müssen Sie Werte einzeln aus der Datei lesen und vor jedem Lesevorgang prüfen, ob das Ende der Datei erreicht ist. Dafür gibt es eine Funktion F. eof().

Dabei ist F der Name des Threads, die Funktion gibt einen booleschen Wert zurück: true oder false, je nachdem, ob das Ende der Datei erreicht ist. Daher kann eine Schleife zum Lesen des Inhalts der gesamten Datei wie folgt geschrieben werden:

//Organisieren zum Lesen von Werten aus einer Datei, Ausführung

//die Schleife wird unterbrochen, wenn wir das Ende der Datei erreichen,

//in diesem Fall gibt F.eof() true zurück

while (!F.eof())

BEISPIEL:

Die Textdatei D:\\game\\noobs.txt speichert reelle Zahlen, zeigt sie auf dem Bildschirm an und berechnet ihre Zahl.

#include „stdafx.h“

#enthalten

#enthalten

#enthalten

#enthalten

Verwenden des Namensraums std;

int main()

setlocale(LC_ALL, "RUS");

int n=0;

float a;

fstream F;

//Öffne die Datei im Lesemodus

F.open("D:\\game\\noobs.txt");

//wenn die Datei korrekt geöffnet wurde, dann

//Schleife zum Lesen von Werten aus einer Datei; die Schleifenausführung wird unterbrochen,

//Wenn wir das Ende der Datei erreichen, gibt F.eof() in diesem Fall true zurück.

while (!F.eof())

//Lesen des nächsten Werts aus Stream F in die Variable a

F>>a;

//den Wert der Variablen a auf dem Bildschirm ausgeben

cout<

//Erhöhe die Anzahl der gelesenen Zahlen

//Den Stream schließen

F.close();

//Geben Sie auf dem Bildschirm die Anzahl der gelesenen Zahlen ein

cout<<"n="<

//Wenn das Öffnen der Datei falsch war, dann die Ausgabe

//Meldungen über das Fehlen einer solchen Datei

sonst cout<<" Файл не существует"<

system("pause");

0 zurückgeben;

C++. Binärdateiverarbeitung

Beim Schreiben von Informationen in eine Binärdatei werden Zeichen und Zahlen als Folge von Bytes geschrieben.

Damit aufschreiben Um Daten in eine Binärdatei zu konvertieren, benötigen Sie:

    Beschreiben Sie eine Dateivariable vom Typ FAIL * mit dem Operator FILE *filename;. Hier ist Dateiname der Name der Variablen, in der der Zeiger auf die Datei gespeichert wird.

    Schreiben Sie Informationen mit der Funktion fwrite in eine Datei

Damit zählen b-Daten aus einer Binärdatei benötigen Sie:

    Beschreiben Sie eine Variable vom Typ FILE *

    Öffnen Sie eine Datei mit der Funktion fopen

    Schließen Sie eine Datei mit der Funktion fclose

Grundfunktionen, die für die Arbeit mit Binärdateien erforderlich sind.

Für Entdeckungen Die Datei ist für die fopen-Funktion gedacht.

DATEI *fopen(const *Dateiname, const char *Modus)

Hier ist Dateiname eine Zeichenfolge, die den vollständigen Namen der geöffneten Datei speichert, Modus ist eine Zeichenfolge, die den Modus zum Arbeiten mit der Datei bestimmt; Folgende Werte sind möglich:

„rb“ – Binärdatei im Lesemodus öffnen;

„wb“ – eine Binärdatei für die Aufnahme erstellen; Wenn es vorhanden ist, wird sein Inhalt gelöscht.

„ab“ – eine Binärdatei erstellen oder öffnen, um sie an das Ende der Datei anzuhängen;

„rb+“ – eine vorhandene Binärdatei im Lese-/Schreibmodus öffnen;

„wb+“ – Binärdatei im Lese-/Schreibmodus öffnen, die vorhandene Datei wird gelöscht;

„ab+“ – eine Binärdatei wird geöffnet oder erstellt, um vorhandene Informationen zu korrigieren und neue Informationen am Ende der Datei hinzuzufügen.

Die Funktion gibt NULL in der Dateivariablen f zurück, wenn die Datei nicht erfolgreich geöffnet wird. Nach dem Öffnen einer Datei steht ihr 0. Byte zur Verfügung, der Dateizeiger ist 0, dessen Wert sich beim Lesen oder Schreiben um die Anzahl der gelesenen (geschriebenen) Bytes verschiebt. Der aktuelle Wert des Dateizeigers ist die Bytenummer, ab der der Lese- oder Schreibvorgang ausgeführt wird.

Für Schließen Die Datei ist für die Funktion fclose gedacht

int fclose(FILE *Dateiname);

Gibt 0 zurück, wenn die Datei erfolgreich geschlossen wurde, andernfalls NULL.

Die Remove-Funktion ist für Entfernung Dateien.

int remove(const char *Dateiname);

Diese Funktion löscht eine Datei namens filenema von der Festplatte. Die zu löschende Datei muss geschlossen sein. Die Funktion gibt einen Wert ungleich Null zurück, wenn die Datei nicht gelöscht werden konnte.

Für Umbenennung Dateien, die Umbenennungsfunktion ist vorgesehen für:

int rename(const char *oldfilename, const char *newfilename);

Der erste Parameter ist der alte Dateiname, der zweite der neue. Gibt 0 zurück, wenn das Programm erfolgreich beendet wird.

Lektüre aus einer Binärdatei erfolgt mit der Funktion fread:

fread(void *ptr, size, n, FILE *filename);

Die Funktion fread liest n Elemente der Größe size aus der Datei Dateiname in ein Array ptr. Die Funktion gibt die Anzahl der gelesenen Elemente zurück. Nach dem Lesen aus einer Datei wird der Zeiger um n*große Bytes verschoben.

Aufzeichnen in eine Binärdatei erfolgt mit der Funktion fwrite:

fwrite(const void *ptr, size, n, FILE *filename);

Die Funktion fwrite schreibt aus einem Array ptr mit n Elementen der Größe size in die Datei Dateiname. Die Funktion gibt die Anzahl der geschriebenen Elemente zurück. Nach dem Schreiben von Informationen in die Datei wird der Zeiger um n*große Bytes verschoben.

Für End-of-File-Kontrolle Es gibt eine Funktion feof:

int feof(FILE *Dateiname);

Es gibt einen Wert ungleich Null zurück, wenn das Ende der Datei erreicht ist.

BEISPIEL:

Erstellen Sie eine Binärdatei D:\\game\\noobs.dat und schreiben Sie n ganze und n reelle Zahlen hinein.

#include „stdafx.h“

#enthalten

Verwenden des Namensraums std;

int main()

setlocale(LC_ALL, "RUS");

int n, i;

Doppel a;

//Erstelle eine Binärdatei im Schreibmodus

f=fopen("D:\\game\\noobs.dat", "wb");

// Eingang ZahlenN

cout<<"n="; cin>>n;

fwrite(&n, sizeof(int), 1, f);

//Schleife zur Eingabe von n reellen Zahlen

für (i=0; i

//Geben Sie die nächste reelle Zahl ein

cout<<"a=";

cin>>a;

//Eine reelle Zahl in eine Binärdatei schreiben

fwrite(&a, sizeof(double), 1, f);

// schließen Datei

fclose(f);

system("pause");

0 zurückgeben;

BEISPIEL:

Zeigen Sie den Inhalt der Binärdatei D:\\game\\noobs.dat an, die in der vorherigen Aufgabe erstellt wurde

#include „stdafx.h“

#enthalten

Verwenden des Namensraums std;

int main()

setlocale(LC_ALL, "RUS");

int n, i;

Doppel a;

DATEI *f; //beschreibe die Dateivariable

//vorhandene Binärdatei im Lesemodus öffnen

//eine ganze Zahl aus der Datei in die Variable n lesen

//n auf dem Bildschirm ausgeben

cout<<"n="<

//Speicher für ein Array von n Zahlen zuweisen

a=neues Double[n];

//n reelle Zahlen aus Datei in Array a einlesen

//das Array auf dem Bildschirm ausgeben

für (i=0; i

cout<

cout<

// schließen Datei

fclose(f);

system("pause");

0 zurückgeben;

Binärdatei- sequentielle Datenstruktur, nach dem Öffnen einer Datei steht das erste darin gespeicherte Byte zur Verfügung. Sie können Daten sequentiell aus einer Datei schreiben oder lesen. Nehmen wir an, Sie müssen die fünfzehnte Zahl zählen und dann die erste. Mittels sequentiellem Zugriff kann dies folgendermaßen erfolgen:

int n, i;

Doppel a;

DATEI *f;

f=fopen("D:\\game\\noobs.dat", "rb");

für (i=0; i<15; i++)

fclose(f);

f=fopen("D:\\game\\noobs.dat", "rb");

fread(&a, sizeof(double), 1, f);

fclose(f);

Wie Sie sehen, ist das Lesen von Zahlen aus einer Datei und das anschließende erneute Öffnen der Datei nicht die bequemste Methode. Es ist viel bequemer, die Funktion fseek zu verwenden, um den Dateizeiger auf ein bestimmtes Byte zu verschieben.

int fseek(FILE *filename, long int offset, int origin);

Die Funktion setzt den aktuellen Dateipositionszeiger F entsprechend den Ursprungs- und Offsetwerten. Der Offset-Parameter entspricht der Anzahl der Bytes, um die der Dateizeiger relativ zum durch den Ursprungsparameter angegebenen Ursprung versetzt wird. Der Wert für den Ursprungsparameter muss einer der folgenden im stdio.h-Header definierten Offset-Werte sein:

SEEK_SET – vom Anfang der Datei;

SEEK_CUR – von der aktuellen Position;

SEEK_END – vom Ende der Datei.

Die Funktion gibt einen Nullwert zurück, wenn der Vorgang erfolgreich war, und einen Wert ungleich Null, wenn der Offset fehlgeschlagen ist.

Die Funktion fseek implementiert tatsächlich den direkten Zugriff auf jeden Wert in einer Datei. Sie müssen lediglich den Speicherort (Bytenummer) des Werts in der Datei kennen. Schauen wir uns die Verwendung des Direktzugriffs in Binärdateien am Beispiel des folgenden Problems an.

BEISPIEL

Tauschen Sie in der zuvor erstellten Binärdatei D:\\game\\noobs.dat die größten und kleinsten reellen Zahlen aus.

Der Algorithmus zur Lösung des Problems besteht aus folgenden Phasen:

    Lesen von reellen Zahlen aus einer Datei in Array a.

    Suchen Sie im Array a nach den maximalen (max) und minimalen (min) Werten und deren Zahlen (imax, imin).

    Bewegen Sie den Dateizeiger auf den Maximalwert und schreiben Sie min.

    Bewegen des Dateizeigers auf den Minimalwert und Schreiben von max.

Nachfolgend finden Sie den Text des Programms zur Lösung des Problems mit Kommentaren.

#include „stdafx.h“

#enthalten

Verwenden des Namensraums std;

int main()

setlocale(LC_ALL, "RUS");

int n, i, imax, imin;

double *a, max, min;

DATEI *f;

//öffne eine Datei im Lese-/Schreibmodus

f=fopen("D:\\game\\noobs.dat", "rb+");

//Zahl aus Datei in Variable n lesen

//reelle Zahlen in der Datei

fread(&n, sizeof(int), 1, f);

cout<<"n="<

//Speicher zum Speichern reeller Zahlen reservieren,

//was im Array a gespeichert wird

a=neues Double[n];

//aus Datei in Array und reelle Zahlen lesen

fread(a, sizeof(double), n, f);

//Suche nach maximalen und minimalen Elementen

//im Array a und ihre Indizes

für (imax=imin=0, max=min=a, i=1; i

if (a[i]>max)

max=a[i];

wenn (a[i]

min=a[i];

// ziehen um Zeiger Zu maximal Element

fseek(f, sizeof(int)+imax*sizeof(double), SEEK_SET);

//mindestens statt maximales Dateielement schreiben

fwrite(&min, sizeof(double), 1, f);

// ziehen um Zeiger Zu Minimum Element

fseek(f, sizeof(int)+imin*sizeof(double), SEEK_SET);

//maximales statt minimales Dateielement aufzeichnen

fwrite(&max, sizeof(double), 1, f);

//Schließen der Datei

fclose(f);

//Speicher freigeben

löschen [ ]A;

system("pause");

In diesem Abschnitt werden zwei Möglichkeiten zum Arbeiten mit Dateien und der Standard-MFC-Klasse CFileDialog erläutert.


1. Arbeiten mit Dateien in C (funktioniert auch in C++).


    #enthalten
    #enthalten

Void main(void)
{
DATEI *Datei;
char* file_name = "file.txt";
char load_string = "none";

File = fopen(file_name, "w");

Fputs("string", file);

File = fopen(file_name, "r");
if(Datei != 0)
{
fgets(load_string, 50 , file);
cout)
anders
{
cout)
fclose(Datei);
) Beschreibungen der Funktionen zum Arbeiten mit Dateien finden Sie in der Bibliothek stdio.h
Zuerst müssen Sie einen Zeiger auf eine Variable vom Typ FILE erstellen ( DATEI* Datei;).
Das Öffnen einer Datei erfolgt durch Aufruf der fopen-Funktion ( file = fopen(file_name, "w");)
Der erste Parameter dieser Funktion ist der Dateiname, der zweite gibt an, in welchem ​​Modus die Datei geöffnet werden soll. „w“- zur Aufnahme geöffnet, "R"- zum Lesen geöffnet, "A"- Hinzufügen von Dateien (dies sind die am häufigsten verwendeten Modi, obwohl es noch andere gibt). Das Schreiben und Lesen von Daten aus einer Datei erfolgt durch folgende Funktionen: fputc, fputs, fgetc, fgets, fprintf, fscanf(Eine Beschreibung dieser Funktionen finden Sie unter stdio.h).
Das Schließen einer Datei erfolgt durch Aufruf der Funktion fclose ( fclose(Datei);).

Arbeiten mit Dateien mithilfe von MFC (Klassen CFile, CStdioFile, ...) und der Standard-MFC-Klasse CFileDialog.


Die MFC-Bibliothek enthält mehrere Klassen zum Arbeiten mit Dateien. Die unten besprochenen Klassen erben von der Basisklasse

CFile.

Datei der Klasse CF

CFileEntwickelt, um mit Dateien zu arbeiten. Es erleichtert die Verwendung von Dateien, indem es eine Datei als Objekt darstellt, das erstellt, gelesen, geschrieben usw. werden kann.

Um auf eine Datei zuzugreifen, müssen Sie zunächst ein Objekt der CFile-Klasse erstellen. Mit dem Klassenkonstruktor können Sie eine Datei sofort nach dem Erstellen eines solchen Objekts öffnen. Sie können die Datei jedoch später mit der Methode öffnen

Offen.

Dateien öffnen und erstellen

Nach dem Erstellen des Klassenobjekts CFileSie können eine Datei öffnen, indem Sie die Methode aufrufenOffen. Die Methode muss den Pfad zur zu öffnenden Datei und den Modus ihrer Verwendung angeben. MethodenprototypOffenhat die folgende Form:

Virtual BOOL Open(LPCTSTR lpszFileName, UINT nOpenFlags, CFileException* pError=NULL);

Als lpszFileName-Parameter müssen Sie den Namen der zu öffnenden Datei angeben. Sie können nur den Dateinamen oder den vollständigen Dateinamen einschließlich des vollständigen Pfads angeben.

Der zweite Parameter, nOpenFlags, gibt die Aktion an, die die Open-Methode für die Datei ausführt, sowie die Attribute der Datei. Nachfolgend sind einige mögliche Werte für den nOpenFlags-Parameter aufgeführt:

  • CFile::modeCreate – Erstellt eine neue Datei. Wenn die angegebene Datei vorhanden ist, wird ihr Inhalt gelöscht und die Dateilänge auf Null gesetzt.
  • CFile::modeNoTruncate – Diese Datei soll in Verbindung mit der Datei CFile::modeCreate verwendet werden. Wenn eine vorhandene Datei erstellt wird, wird deren Inhalt nicht gelöscht.

  • CFile::modeRea d – Die Datei wird schreibgeschützt geöffnet.
  • CFile::modeReadWrite – Die Datei wird zum Schreiben und Lesen geöffnet.
  • CFile::modeWrite – Die Datei wird nur zum Schreiben geöffnet.
  • CFile::typeText – Wird von von der CFile-Klasse abgeleiteten Klassen wie CStdioFile verwendet, um mit Dateien im Textmodus zu arbeiten. Der Textmodus konvertiert die Kombination aus einem Wagenrücklaufzeichen und einem Zeilenvorschubzeichen.
  • CFile::Binary – Wird von von der CFile-Klasse abgeleiteten Klassen wie CStdioFile verwendet, um mit Dateien im Binärmodus zu arbeiten.
  • Optionaler Parameter pError, der ein Zeiger auf ein Klassenobjekt ist CFileException, wird nur verwendet, wenn die Ausführung einer Operation an der Datei einen Fehler verursachen würde. In diesem Fall werden zusätzliche Informationen in das Objekt geschrieben, auf das pError zeigt.

    Methode OffenGibt einen Wert ungleich Null zurück, wenn die Datei geöffnet ist, und Null bei einem Fehler. Ein Fehler beim Öffnen einer Datei kann beispielsweise auftreten, wenn die Open-Methode zum Lesen einer nicht vorhandenen Datei angegeben wird.

    Datei-ID öffnen

    Die CFile-Klasse enthält ein Datenelement m_hFile vom Typ UINT. Es speichert die Kennung der geöffneten Datei. Wenn ein Objekt der CFile-Klasse bereits erstellt wurde, die Datei jedoch noch nicht geöffnet wurde, wird die hFileNull-Konstante in die m_hFile-Variable geschrieben.

    Normalerweise wird die Kennung der geöffneten Datei nicht direkt verwendet. Klassenmethoden CFileermöglichen Ihnen die Durchführung fast aller Vorgänge mit Dateien und erfordern keine Angabe einer Dateikennung. Da m_hFile ein Klassenelement ist, hat die Implementierung seiner Methoden immer freien Zugriff darauf.

    Dateien schließen

    Nach Abschluss der Arbeit mit der Datei muss diese geschlossen werden. Klasse CFileverfügt hierfür über eine spezielle Close-Methode. Es ist zu beachten, dass, wenn ein Objekt der CFile-Klasse erstellt und eine Datei geöffnet wurde und dann das Objekt gelöscht wird, die zugehörige Datei automatisch mithilfe eines Destruktors geschlossen wird.

    Dateien lesen und schreiben

    Für den Zugriff auf Dateien gibt es mehrere Klassenmethoden. CFile: Lesen, ReadHuge, Schreiben, WriteHuge, Flush. Methoden Lesen und ReadHuge dienen dazu, Daten aus einer zuvor geöffneten Datei zu lesen. Auf 32-Bit-Betriebssystemen können beide Methoden gleichzeitig mehr als 65535 Bytes aus einer Datei lesen. Die ReadHuge-Spezifikation gilt als veraltet und wird nur aus Kompatibilitätsgründen mit 16-Bit-Betriebssystemen beibehalten.

    Aus der Datei gelesene Daten werden in den lpBuf-Puffer geschrieben. Der Parameter nCount gibt die Anzahl der Bytes an, die aus der Datei gelesen werden sollen. Tatsächlich werden möglicherweise weniger Bytes aus der Datei gelesen, als durch den Parameter nCount angefordert wird. Dies geschieht, wenn beim Lesen das Ende der Datei erreicht wird. Die Methoden geben die Anzahl der aus der Datei gelesenen Bytes zurück.

    Die Methoden Write und WriteHuge sind zum Schreiben in eine Datei vorgesehen. Auf 32-Bit-Betriebssystemen können beide Methoden gleichzeitig mehr als 65535 Bytes in eine Datei schreiben. Methoden schreiben Bytes aus dem lpBuf-Puffer in die geöffnete Datei nCount. Wenn ein Schreibfehler auftritt, beispielsweise wenn die Festplatte voll ist, rufen die Methoden eine Ausnahmebehandlung auf.

    Flush-Methode

    Wenn die Methode „Write“ oder „WriteHuge“ zum Schreiben von Daten auf die Festplatte verwendet wird, verbleiben diese möglicherweise einige Zeit in einem temporären Puffer. Um sicherzustellen, dass die erforderlichen Änderungen an der Datei auf der Festplatte vorgenommen werden, müssen Sie die Flush-Methode verwenden.

    Dateioperationen

    Die Klasse umfasst Methoden, mit denen Sie verschiedene Vorgänge an Dateien ausführen können, z. B. Kopieren, Umbenennen, Löschen und Ändern von Attributen.

    Um den Dateinamen zu ändern, enthält die CFile-Klasse eine statische Methode Umbenennen, der die Funktionen dieses Befehls ausführt. Die Methode kann nicht zum Umbenennen von Verzeichnissen verwendet werden. Tritt ein Fehler auf, löst die Methode eine Ausnahme aus.

    In der CFile-Klasse ist eine statische Methode zum Löschen von Dateien enthalten Entfernen, mit dem Sie die angegebene Datei löschen können. Mit dieser Methode können Sie keine Verzeichnisse löschen. Wenn die Datei nicht gelöscht werden kann, löst die Methode eine Ausnahme aus.

    Um Datum und Uhrzeit der Dateierstellung, ihre Länge und Attribute zu bestimmen, wird eine statische Methode verwendet Status bekommen. Es gibt zwei Arten von Methoden: Die erste ist als virtuelle Methode und die zweite als statische Methode definiert.

    Virtuelle Version der Methode Status bekommenBestimmt den Öffnungsstatus der Datei, die diesem CFile-Klassenobjekt zugeordnet ist. Diese Methode wird nur aufgerufen, wenn ein CFile-Klassenobjekt erstellt und die Datei geöffnet wird.

    Statische Version der Methode Status bekommenermöglicht es Ihnen, die Eigenschaften einer Datei zu bestimmen, die keinem Objekt der CFile-Klasse zugeordnet ist. Um diese Methode zu verwenden, ist es nicht erforderlich, die Datei zuerst zu öffnen.

    Sperren

    Die Klasse enthält Methoden LockRange Und UnlockRange, mit denen ein oder mehrere Dateidaten für den Zugriff durch andere Prozesse gesperrt werden können. Wenn eine Anwendung versucht, Daten erneut zu sperren, die zuvor von dieser oder einer anderen Anwendung gesperrt wurden, wird eine Ausnahme ausgelöst. Das Sperren ist einer der Mechanismen, der es mehreren Anwendungen oder Prozessen ermöglicht, gleichzeitig an derselben Datei zu arbeiten, ohne sich gegenseitig zu stören.

    Mit der Methode können Sie eine Sperre setzen LockRange. Um installierte Sperren zu entfernen, müssen Sie die Methode verwendenUnlockRange. Sind in einer Datei mehrere Sperren gesetzt, so muss jede Sperre durch einen eigenen Methodenaufruf freigegeben werdenUnlockRange.

    Positionierung

    Um den aktuellen Dateipositionszeiger an eine neue Position zu verschieben, können Sie eine der folgenden Klassenmethoden verwenden CFile - Suchen, SuchenToBegin, SuchenToEnd. Zur Klasse CFileenthält auch Methoden, mit denen Sie die Dateilänge festlegen und ändern können, -GetLength, SetLength.

    Beim Öffnen einer Datei befindet sich die aktuelle Dateipositionsanzeige ganz am Anfang der Datei. Wenn ein Datenelement gelesen oder geschrieben wird, bewegt sich der Zeiger der aktuellen Position zum Ende der Datei und zeigt auf die Daten, die beim nächsten Lese- oder Schreibvorgang in der Datei gelesen oder geschrieben werden.

    Um den aktuellen Dateipositionszeiger an eine beliebige Stelle zu verschieben, können Sie die universelle Methode verwenden

    Suchen. Damit können Sie den Zeiger um eine bestimmte Anzahl von Bytes relativ zur Start-, End- oder aktuellen Zeigerposition verschieben.

    Um den Zeiger an den Anfang oder das Ende einer Datei zu bewegen, ist es am bequemsten, spezielle Methoden zu verwenden. Methode

    SeekToBeginVerschiebt den Zeiger an den Anfang der Datei und der MethodeSeekToEnd- bis zu seinem Ende.

    Um die Länge einer geöffneten Datei zu bestimmen, ist es jedoch nicht erforderlich, den Zeiger zu bewegen. Sie können die Methode verwenden

    GetLength. Diese Methode gibt auch die Länge der geöffneten Datei in Bytes zurück. MethodeSetLengthermöglicht Ihnen, die Länge der geöffneten Datei zu ändern. Wenn diese Methode die Dateigröße erhöht, ist der Wert der letzten Bytes undefiniert.

    Mit der Methode kann die aktuelle Position des Dateizeigers ermittelt werden

    GetPosition. Von der Methode zurückgegebenGetPositionDer 32-Bit-Wert gibt den Zeigeroffset vom Anfang der Datei an.

    Eigenschaften der offenen Datei

    Um den Speicherort einer geöffneten Datei auf der Festplatte zu ermitteln, müssen Sie die Methode aufrufen GetFilePath. Diese Methode gibt ein Objekt der Klasse zurückCString, das den vollständigen Pfad der Datei enthält, einschließlich Laufwerksname, Verzeichnissen, Dateiname und Dateierweiterung.

    Wenn Sie nur den Namen und die Erweiterung einer geöffneten Datei ermitteln müssen, können Sie die Methode verwenden GetFileName. Es gibt ein CString-Objekt zurück, das den Dateinamen enthält. Wenn Sie nur den Namen einer geöffneten Datei ohne Erweiterung herausfinden müssen, verwenden Sie die MethodeGetFileTitle.

    Mit der folgenden Methode der CFile-Klasse können Sie den Dateipfad festlegen. Diese Methode erstellt, kopiert oder ändert den Dateinamen nicht; sie füllt nur das entsprechende Datenelement im CFile-Klassenobjekt auf.

    Klasse C

    MemFile

    Die MFC-Bibliothek enthält die Klasse

    CMemFile, geerbt von der BasisklasseCFile. Klasse CMemFilestellt eine Datei dar, die sich im RAM befindet. Mit KlassenobjektenCMemFiledas gleiche wie bei KlassenobjektenCFile. Der Unterschied besteht darin, dass die Datei mit dem Objekt verknüpft istCMemFilebefindet sich nicht auf der Festplatte, sondern im RAM des Computers. Aus diesem Grund sind Vorgänge mit einer solchen Datei viel schneller als mit normalen Dateien.

    Arbeiten mit Klassenobjekten

    CMemFilekönnen Sie fast alle Methoden der Klasse verwendenCFiledie oben beschrieben wurden. Sie können Daten in eine solche Datei schreiben oder sie lesen. Zusätzlich zu diesen Methoden enthält die KlasseCMemFilezusätzliche Methoden enthalten.

    Es gibt zwei verschiedene Konstruktoren zum Erstellen von Objekten der CMemFile-Klasse. Der erste CMemFile-Konstruktor hat nur einen optionalen Parameter nGrowBytes:

    CMemFile(UINT nGrowBytes=1024);

    Dieser Konstruktor erstellt eine leere Datei im RAM. Nach der Erstellung wird die Datei automatisch geöffnet (kein Aufruf der Ope-Methode erforderlich).

    N).

    Wenn das Schreiben in eine solche Datei beginnt, wird automatisch ein Speicherblock zugewiesen. So erhalten Sie Speicherklassenmethoden

    CMemFileRufen Sie Standardfunktionen aufmalloc, realloc Und frei. Wenn der zugewiesene Speicherblock nicht ausreicht, wird seine Größe erhöht. Der Speicherblock der Datei wird in Teilen von nGrowBytes Bytes vergrößert. Nach dem Löschen eines KlassenobjektsCMemFileBenutzter Speicher wird automatisch an das System zurückgegeben.

    Der zweite Konstruktor der CMemFile-Klasse verfügt über einen komplexeren Prototyp. Dieser Konstruktor wird in Fällen verwendet, in denen der Programmierer selbst Speicher für die Datei zuweist:

    CMemFile(BYTE* lpBuffer, UINT nBufferSize, UINT nGrowBytes=0);

    Der Parameter lpBuffer gibt den Puffer an, der für die Datei verwendet werden soll. Die Puffergröße wird durch den Parameter nBufferSize bestimmt.

    Der optionale Parameter nGrowBytes wird umfassender verwendet als im Konstruktor der ersten Klasse. Wenn nGrowBytes Null enthält, enthält die generierte Datei die Daten aus dem lpBuffer. Die Länge einer solchen Datei entspricht nBufferSize.

    Wenn nGrowBytes größer als Null ist, wird der Inhalt von lpBuffer ignoriert. Wenn außerdem mehr Daten in eine solche Datei geschrieben werden, als in den zugewiesenen Puffer passen, erhöht sich deren Größe automatisch. Der Speicherblock der Datei wird in Teilen von nGrowBytes Bytes vergrößert.

    CMemFileermöglicht es Ihnen, einen Zeiger auf den von der Datei verwendeten Speicherbereich abzurufen. Über diesen Zeiger können Sie direkt mit dem Inhalt der Datei arbeiten, ohne sich auf Klassenmethoden zu beschränkenCFile. Um einen Zeiger auf einen Dateipuffer zu erhalten, können Sie die Detach-Methode verwenden. Zuvor ist es sinnvoll, die Länge der Datei (und damit die Größe des Speicherpuffers) durch Aufruf der Methode zu ermittelnGetLength. Ablösenschließt die angegebene Datei und gibt einen Zeiger auf den Speicherblock zurück, den sie verwendet. Wenn Sie die Datei erneut öffnen und ihr einen RAM-Block zuordnen müssen, müssen Sie die Methode aufrufenAnfügen.

    Es ist zu beachten, dass die Klasse zum Verwalten des Dateipuffers erforderlich ist

    CMemFileruft Standardfunktionen aufmalloc, realloc Und frei. Um den Speicherverwaltungsmechanismus nicht zu beschädigen, muss daher der lpBuffer-Puffer von den Funktionen erstellt werdenmalloc oder calloc.

    CStdioFile-Klasse

    Wer die Stream-I/O-Funktionen aus der C- und C++-Standardbibliothek gewohnt ist, sollte der Klasse Beachtung schenken

    CStdioFile, geerbt von der BasisklasseCFile. Mit dieser Klasse können Sie gepufferte E/A im Text- und Binärmodus ausführen. Für KlassenobjekteCStdioFileSie können fast alle Methoden der CFile-Klasse aufrufen.CStdioFileEnthält das m_pStream-Datenelement, das einen Zeiger auf die geöffnete Datei enthält. Wenn ein KlassenobjektCStdioFileerstellt, aber die Datei ist noch nicht geöffnet oder geschlossen, dann enthält m_pStream die NULL-Konstante.CStdioFilehat drei verschiedene Konstruktoren. Der erste Konstruktor der CStdioFile-Klasse hat keine Parameter. Dieser Konstruktor erstellt lediglich ein Klassenobjekt, öffnet jedoch keine Dateien. Um eine Datei zu öffnen, müssen Sie die Methode aufrufenOffenBasisklasseCFile.

    Konstruktor zweiter Klasse

    CStdioFilekann aufgerufen werden, wenn die Datei bereits geöffnet ist und Sie ein neues Objekt der CStdioFile-Klasse erstellen und die geöffnete Datei damit verknüpfen müssen. Dieser Konstruktor kann verwendet werden, wenn die Datei mit einer Standardfunktion geöffnet wurdefopen. Der Methodenparameter muss einen Zeiger auf die Datei enthalten, die durch den Aufruf der Standardfunktion erhalten wirdfopen.

    Der dritte Konstruktor kann verwendet werden, wenn Sie ein Klassenobjekt erstellen müssen

    CStdioFile, öffnen Sie eine neue Datei und verknüpfen Sie sie mit dem neu erstellten Objekt.

    Zum Lesen und Schreiben in eine Textdatei enthält die CStdioFile-Klasse zwei neue Methoden:

    ReadString Und WriteString. Mit der ersten Methode können Sie eine Zeichenfolge aus einer Datei lesen und mit der zweiten Methode können Sie sie schreiben.

    Beispiele für das Schreiben und Lesen aus einer Datei

    Hier sind Codefragmente, die die Verwendung von Standarddialogfeldern zur Dateiauswahl und das Verfahren zum Lesen und Schreiben in eine Datei veranschaulichen.

    Eine Datei öffnen und daraus lesen

    CString m_Text; …… // Erstellen eines Standard-Dateiauswahlfelds Öffnen CFileDialog DlgOpen(TRUE,(LPCSTR)"txt",NULL, OFN_HIDEREADONLY,(LPCSTR)" Textdateien (*.txt) |*.txt||"); // Zeigt das Standard-Dateiauswahlfeld an. Öffnen if(DlgOpen.DoModal()==IDOK) ( // ein Objekt erstellen und die Datei zum Lesen öffnen CStdioFile File(DlgOpen.GetPathName(),CFile::modeRead|CFile::typeBinary); // Strings aus Datei lesen CString& ref=m_Text; File.ReadString(ref ); // Es wird eine Referenz auf einen String übergeben m_Text)

    Öffnen und Schreiben aus einer Datei

    CString m_Text; …… // Erstellen eines standardmäßigen SaveAs-Dateiauswahlfelds CFileDialog DlgSaveAs(FALSE,(LPCSTR)"txt",NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, (LPCSTR)" Textdateien (*.txt) |*.txt||"); // Zeigt das Standard-SaveAs-Dateiauswahlfeld an if(DlgSaveAs.DoModal()==IDOK) ( // ein Objekt erstellen und eine Datei zum Schreiben öffnen CStdioFile File(DlgSaveAs.GetPathName(), CFile::modeCreate|CFile::modeWrite|CFile::typeBinary); // in eine String-Datei schreiben File.WriteString((LPCTSTR)m_Text); )
      enthält den Arbeitscode des Programms, das der Einfachheit halber als Konsolenanwendung unter MFC konzipiert ist. Damit das Programm funktioniert, vergessen Sie nicht, Folgendes zu tun:

      Führen Sie das Programm aus – Alles erstellen / neu erstellen (es treten Fehler auf), wählen Sie „Aktive Konfiguration erstellen / festlegen“ – Win 32 Realise, wählen Sie den Menüpunkt „Projekt“, dann „Einstellungen…“, die Registerkarte „C/C++“, Kategorie – Codegenerierung und Wählen Sie im Punkt „Laufzeitbibliothek verwenden“ die Option „Multithreaded“. Danach führen Sie „Build/Rebuild all“ erneut aus und das Programm funktioniert.

    Um den Zugriff zu erleichtern, werden Informationen auf Speichergeräten in Form von Dateien gespeichert.

    Eine Datei ist ein benannter Bereich des externen Speichers, der zum Speichern eines Datenarrays reserviert ist. Die in den Dateien enthaltenen Daten sind sehr unterschiedlicher Natur: Programme in algorithmischer oder maschineller Sprache; Anfangsdaten für den Programmbetrieb oder die Ergebnisse der Programmausführung; Freitexte; grafische Bilder usw.

    Verzeichnis (Ordner, Verzeichnis) – eine benannte Sammlung von Bytes auf einem Speichermedium, die die Namen von Unterverzeichnissen und Dateien enthält und im Dateisystem verwendet wird, um die Organisation von Dateien zu vereinfachen.

    Dateisystem bezeichnet den funktionalen Teil des Betriebssystems, der Vorgänge an Dateien ausführt. Beispiele für Dateisysteme sind FAT (FAT – File Allocation Table), NTFS, UDF (wird auf CDs verwendet).

    Es gibt drei Hauptversionen von FAT: FAT12, FAT16 und FAT32. Sie unterscheiden sich in der Bittiefe der Datensätze in der Plattenstruktur, d.h. die Anzahl der Bits, die zum Speichern der Clusternummer zugewiesen sind. FAT12 wird hauptsächlich für Disketten (bis zu 4 KB) verwendet, FAT16 – für Festplatten mit geringer Kapazität, FAT32 – für FLASH-Laufwerke mit hoher Kapazität (bis zu 32 GB).

    Schauen wir uns den Aufbau des Dateisystems am Beispiel von FAT32 an.

    FAT32-Dateistruktur

    Externe Speichergeräte im FAT32-System verfügen über Blockadressierung statt Byteadressierung. Informationen werden in Blöcken oder Sektoren auf ein externes Speichergerät geschrieben.

    Ein Sektor ist die minimal adressierbare Informationsspeichereinheit auf externen Speichergeräten. Normalerweise ist die Sektorgröße auf 512 Byte festgelegt. Um den Adressraum externer Speichergeräte zu vergrößern, werden Sektoren in Gruppen zusammengefasst, die als Cluster bezeichnet werden.

    Ein Cluster ist ein Zusammenschluss mehrerer Sektoren, die als eigenständige Einheit mit bestimmten Eigenschaften betrachtet werden können. Die Haupteigenschaft eines Clusters ist seine Größe, gemessen in der Anzahl der Sektoren oder der Anzahl der Bytes.

    Das FAT32-Dateisystem hat die folgende Struktur.

    Die zum Schreiben von Dateien verwendeten Cluster sind beginnend mit 2 nummeriert. In der Regel wird Cluster Nr. 2 vom Stammverzeichnis verwendet und ab Cluster Nr. 3 wird das Datenarray gespeichert. Sektoren, die zum Speichern von Informationen oberhalb des Stammverzeichnisses verwendet werden, werden nicht geclustert.
    Die auf der Festplatte erforderliche Mindestdateigröße entspricht 1 Cluster.

    Der Bootsektor beginnt mit den folgenden Informationen:

    • EB 58 90 – unbedingter Sprung und Signatur;
    • 4D 53 44 4F 53 35 2E 30 MSDOS5.0;
    • 00 02 – Anzahl der Bytes im Sektor (normalerweise 512);
    • 1 Byte – Anzahl der Sektoren im Cluster;
    • 2 Bytes – Anzahl der Reservesektoren.

    Darüber hinaus enthält der Bootsektor folgende wichtige Informationen:

    • 0x10 (1 Byte) – Anzahl der FAT-Tabellen (normalerweise 2);
    • 0x20 (4 Bytes) – Anzahl der Sektoren auf der Festplatte;
    • 0x2С (4 Bytes) – Clusternummer des Stammverzeichnisses;
    • 0x47 (11 Bytes) – Datenträgerbezeichnung;
    • 0x1FE (2 Bytes) – Bootsektorsignatur (55 AA).

    Der Dateisysteminformationssektor enthält:

    • 0x00 (4 Bytes) – Signatur (52 52 61 41);
    • 0x1E4 (4 Bytes) – Signatur (72 72 41 61);
    • 0x1E8 (4 Bytes) – Anzahl freier Cluster, -1, wenn unbekannt;
    • 0x1EC (4 Bytes) – Nummer des zuletzt aufgezeichneten Clusters;
    • 0x1FE (2 Bytes) – Signatur (55 AA).

    Die FAT-Tabelle enthält Informationen über den Status jedes Clusters auf der Festplatte. Die unteren 2 Bytes der FAT-Tabelle speichern F8 FF FF 0F FF FF FF FF (was dem Zustand der Cluster 0 und 1 entspricht, die physisch nicht vorhanden sind). Als nächstes enthält der Status jedes Clusters die Nummer des Clusters, in dem die aktuelle Datei fortgesetzt wird, oder die folgenden Informationen:

    • 00 00 00 00 – Cluster ist frei;
    • FF FF FF 0F – Ende der aktuellen Datei.
    • 8 Bytes – Dateiname;
    • 3 Bytes – Dateierweiterung;

    Das Stammverzeichnis enthält eine Reihe von 32-Bit-Informationsdatensätzen zu jeder Datei, die die folgenden Informationen enthalten:

    Bei der Arbeit mit langen Dateinamen (einschließlich russischer Namen) wird der Dateiname mit dem UTF-16-Kodierungssystem kodiert. In diesem Fall werden für die Kodierung jedes Zeichens 2 Bytes zugewiesen. In diesem Fall wird der Dateiname in folgender Struktur geschrieben:

    • 1 Sequenzbyte;
    • 10 Bytes enthalten die unteren 5 Zeichen des Dateinamens;
    • 1-Byte-Attribut;
    • 1 Byte reserviert;
    • 1 Byte – DOS-Namensprüfsumme;
    • 12 Bytes enthalten die unteren 3 Zeichen des Dateinamens;
    • 2 Bytes – Nummer des ersten Clusters;
    • die restlichen Zeichen des langen Namens.

    Arbeiten mit Dateien in C-Sprache

    Für den Programmierer wird eine geöffnete Datei als eine Folge von Daten dargestellt, die gelesen oder geschrieben werden. Wenn eine Datei geöffnet wird, wird sie mit verknüpft I/O-Stream. Ausgabeinformationen werden in den Stream geschrieben, Eingabeinformationen werden aus dem Stream gelesen.

    Wenn ein Stream für E/A geöffnet wird, wird er einer Standard-FILE-Struktur zugeordnet, die in stdio.h definiert ist. Die FILE-Struktur enthält die notwendigen Informationen über die Datei.

    Das Öffnen einer Datei erfolgt mit der Funktion fopen(), die einen Zeiger auf eine FILE-Struktur zurückgibt, die für nachfolgende Vorgänge an der Datei verwendet werden kann.

    DATEI *fopen(name, typ);


    name – Name der zu öffnenden Datei (einschließlich Pfad),
    Typ ist ein Zeiger auf eine Zeichenfolge, die definiert, wie auf die Datei zugegriffen wird:
    • „r“ – Datei zum Lesen öffnen (die Datei muss vorhanden sein);
    • „w“ – eine leere Datei zum Schreiben öffnen; Wenn die Datei vorhanden ist, geht ihr Inhalt verloren.
    • „a“ – Datei zum Schreiben bis zum Ende öffnen (zum Anhängen); die Datei wird erstellt, wenn sie nicht existiert;
    • „r+“ – Datei zum Lesen und Schreiben öffnen (die Datei muss vorhanden sein);
    • „w+“ – eine leere Datei zum Lesen und Schreiben öffnen; Wenn die Datei vorhanden ist, geht ihr Inhalt verloren.
    • „a+“ – Datei zum Lesen und Anhängen öffnen; wenn die Datei nicht existiert, wird sie erstellt.

    Der Rückgabewert ist ein Zeiger auf den offenen Stream. Wenn ein Fehler auftritt, wird NULL zurückgegeben.

    Die Funktion fclose() schließt den Stream oder die Streams, die mit Dateien verknüpft sind, die mit der Funktion fopen() geöffnet wurden. Der zu schließende Stream wird durch das Argument der Funktion fclose() bestimmt.

    Rückgabewert: Wert 0, wenn der Stream erfolgreich geschlossen wurde; konstanter EOF, wenn ein Fehler aufgetreten ist.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    #enthalten
    int main() (
    DATEI *fp;
    char name = "my.txt" ;
    if ((fp = fopen(name, "r" )) == NULL )
    {
    printf( "Datei konnte nicht geöffnet werden");
    getchar();
    0 zurückgeben;
    }
    // Die Datei konnte erfolgreich geöffnet werden
    ... // erforderliche Aktionen für Daten
    fclose(fp);
    getchar();
    0 zurückgeben;
    }

    Ein Zeichen aus einer Datei lesen:

    char fgetc(stream);


    Das Funktionsargument ist ein Zeiger auf einen Stream vom Typ FILE. Die Funktion gibt den Code des gelesenen Zeichens zurück. Wenn das Ende der Datei erreicht ist oder ein Fehler auftritt, wird die Konstante EOF zurückgegeben.

    Schreiben eines Symbols in eine Datei:

    fputc(char, stream);

    Die Argumente der Funktion sind ein Zeichen und ein Zeiger auf einen Stream vom Typ FILE. Die Funktion gibt den Code des gelesenen Zeichens zurück.

    Die Funktionen fscanf() und fprintf() ähneln den Funktionen scanf() und printf(), arbeiten jedoch mit Datendateien und haben einen Dateizeiger als erstes Argument.

    fscanf(stream, „InputFormat“, Argumente);

    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.

    Für den Programmierer wird eine geöffnete Datei als eine Folge von Daten dargestellt, die gelesen oder geschrieben werden. Wenn eine Datei geöffnet wird, wird sie mit verknüpft I/O-Stream . Ausgabeinformationen werden in den Stream geschrieben, Eingabeinformationen werden aus dem Stream gelesen.

    Wenn ein Stream für E/A geöffnet wird, wird er einer Standard-FILE-Struktur zugeordnet, die in stdio.h definiert ist. Die FILE-Struktur enthält die notwendigen Informationen über die Datei.

    Das Öffnen einer Datei erfolgt mit der Funktion fopen(), die einen Zeiger auf eine Struktur vom Typ FILE zurückgibt, der für nachfolgende Operationen an der Datei verwendet werden kann.

    DATEI *fopen(name, typ);

    name – Name der zu öffnenden Datei (einschließlich Pfad),
    Typ – Zeiger auf eine Zeichenfolge, die definiert, wie auf die Datei zugegriffen wird:

    · „r“ – Datei zum Lesen öffnen (die Datei muss vorhanden sein);

    · „w“ – eine leere Datei zum Schreiben öffnen; Wenn die Datei vorhanden ist, geht ihr Inhalt verloren.

    · „a“ – Datei zum Schreiben bis zum Ende öffnen (zum Anhängen); die Datei wird erstellt, wenn sie nicht existiert;

    · „r+“ – Datei zum Lesen und Schreiben öffnen (die Datei muss vorhanden sein);

    · „w+“ – eine leere Datei zum Lesen und Schreiben öffnen; Wenn die Datei vorhanden ist, geht ihr Inhalt verloren.

    · „a+“ – Datei zum Lesen und Anhängen öffnen; wenn die Datei nicht existiert, wird sie erstellt.

    Der Rückgabewert ist ein Zeiger auf den offenen Stream. Wenn ein Fehler erkannt wird, wird NULL zurückgegeben.

    Die Funktion fclose() schließt den Stream oder die Streams, die mit Dateien verknüpft sind, die mit der Funktion fopen() geöffnet wurden. Der zu schließende Stream wird durch das Argument der Funktion fclose() bestimmt.

    Rückgabewert: Wert 0, wenn der Stream erfolgreich geschlossen wurde; konstanter EOF, wenn ein Fehler aufgetreten ist.

    #enthalten
    int main()

    char name="my.txt";

    if(fp = fopen(name, "r")!=NULL)

    // Konnte die Datei geöffnet werden?
    ... // erforderliche Aktionen für Daten

    else printf("Datei konnte nicht geöffnet werden");

    Ein Zeichen aus einer Datei lesen:

    char fgetc(stream);

    Das Funktionsargument ist ein Zeiger auf einen Stream vom Typ FILE. Die Funktion gibt den Code des gelesenen Zeichens zurück. Wenn das Ende der Datei erreicht ist oder ein Fehler auftritt, wird die Konstante EOF zurückgegeben.
    Schreiben eines Symbols in eine Datei:

    fputc(char, stream);

    Die Argumente der Funktion sind ein Zeichen und ein Zeiger auf einen Stream vom Typ FILE. Die Funktion gibt den Code des gelesenen Zeichens zurück.

    Die Funktionen fscanf() und fprintf() ähneln den Funktionen scanf() und printf(), arbeiten jedoch mit Datendateien und haben als erstes Argument einen Zeiger auf die Datei.

    fscanf(stream, „Eingabeformat“, Argumente);
    fprintf(stream, „Ausgabeformat“, Argumente);

    Die Funktionen fgets() und fputs() sind für die Eingabe/Ausgabe von Zeichenfolgen konzipiert; sie sind analog zu den Funktionen gets() und puts() für die Arbeit mit Dateien.

    fgets(Zeiger auf Zeile, Anzahl der Zeichen, Stream);

    Zeichen werden aus dem Stream gelesen, bis ein Zeilenumbruchzeichen „\n“ gelesen wird, das in der Zeichenfolge enthalten ist, oder bis der Stream EOF beendet oder die maximale Anzahl von Zeichen gelesen wurde. Das Ergebnis wird in einen String-Zeiger gestellt und endet mit dem Nullzeichen „\0“. Die Funktion gibt die Adresse der Zeichenfolge zurück.

    fputs(Zeiger auf String, Stream);

    Kopiert eine Zeichenfolge von der aktuellen Position in den Stream. Das abschließende Nullzeichen wird nicht kopiert.
    Beispiel Geben Sie die Nummer ein und speichern Sie sie in der Datei s1.txt. Lesen Sie die Zahl aus der Datei s1.txt aus, erhöhen Sie sie um 3 und speichern Sie sie in der Datei s2.txt.