Fonctions C avec des fichiers texte. Travailler avec des fichiers texte

Le mécanisme d'E/S développé par , n'est pas conforme au style généralement accepté de programmation orientée objet aujourd'hui. De plus, il utilise fortement des opérations de pointeur qui sont considérées comme potentiellement dangereuses dans les environnements d'exécution de code sécurisés modernes. Une alternative lors du développement d’applications est le mécanisme des classes d’E/S standard fourni par le standard de langage C++.

Ouverture de fichiers

Les classes les plus couramment utilisées sont ifstream pour la lecture, ofstream pour l'écriture et fstream pour la modification de fichiers.

Toutes les classes d'E/S threadées sont indirectement dérivées de l'ancêtre commun iOS, héritant entièrement de ses fonctionnalités. Ainsi, le mode d'ouverture du fichier est spécifié par le membre de données du type d'énumération open_mode, qui est défini comme suit :

Enum open_mode ( app, binaire, in, out, trunc, ate );

Vous trouverez ci-dessous les valeurs possibles des drapeaux et leur objectif.

Par exemple, pour ouvrir un fichier nommé test.txt pour lire des données sous forme binaire, vous écrivez :

fichier ifstream ; file.open("test.txt", ios::in | ios::binary);

L'opérateur logique OU (|) vous permet de créer un mode avec n'importe quelle combinaison d'indicateurs. Ainsi, pour que lors de l'ouverture d'un fichier par entrée, vous n'écrasiez pas accidentellement un fichier existant du même nom, vous devez utiliser le formulaire suivant :

Fichier hors flux ; file.open("test.txt", ios::out | ios::app);

On suppose que le fichier d'en-tête correspondant est inclus dans le projet :

#inclure

Pour vérifier si le fichier a été ouvert avec succès, vous pouvez utiliser la construction

If (!file) ( //Gestion de l'erreur d'ouverture du fichier)

Opérateurs d’inclusion et d’extraction

Remplacé dans les classes de gestion de fichiers opérateur d'inclusion (<<) записывает данные в файловый поток. Как только вы открыли файл для записи, можно записывать в него текстовую строку целиком:

Déposer<< "Это строка текста";

Vous pouvez également écrire une chaîne de texte en plusieurs parties :

Déposer<< "Это " << "строка " << "текста";

L'instruction endl termine la ligne saisie par un retour chariot :

Déposer<< "Это строка текста" << endl;

À l'aide de l'opérateur include, il est facile d'écrire les valeurs de variables ou d'éléments de tableau dans un fichier :

Fichier Ofstream("Temp.txt"); char buff = "Le tableau de texte contient des variables" ; int vx = 100 ; flotteur pi = 3,14159 ; déposer<< buff << endl << vx << endl << pi << endl;

À la suite de l'exécution du code, trois lignes du fichier texte Temp.txt sont formées :

Le tableau de texte contient des variables 100 3.14159

Notez que les valeurs numériques sont écrites dans le fichier sous forme de chaînes de texte plutôt que de valeurs binaires.

Opérateur de récupération(>>) produit l’effet inverse. Il semblerait que pour extraire les caractères du fichier Temp.txt écrit précédemment, vous écririez un code comme celui-ci :

Fichier Ifstream("Temp.txt"); buff de charbon; intvx; flotter pi ; fichier >> buff >> vx >> pi;

Cependant, l'opérateur d'extraction s'arrêtera au premier délimiteur qu'il rencontrera (espace, tabulation ou nouvelle ligne). Ainsi, lors de l'analyse de la phrase « Le tableau de texte contient des variables », seul le mot « Texte » sera écrit dans le tableau buff, l'espace est ignoré et le mot « tableau » deviendra la valeur de la variable vx entière, et le code l’exécution « tournera mal » avec une violation inévitable de la structure des données. Ensuite, en discutant de la classe ifstream, nous montrerons comment organiser correctement la lecture du fichier de l'exemple précédent.

classe ifstream : lecture de fichiers

Comme son nom l'indique, la classe ifstream est conçue pour saisir un flux de fichiers. Les principales méthodes du cours sont listées ci-dessous. La plupart d'entre eux sont hérités de la classe istream et surchargés pour étendre la fonctionnalité parent. Par exemple, la fonction get, selon le paramètre d'appel, peut lire non seulement un seul caractère, mais également un bloc de caractères.

Il est maintenant clair comment l'exemple précédent doit être modifié pour que l'utilisation de l'opérateur d'extraction de données donne le résultat attendu :

Fichier Ifstream("Temp.txt"); buff de charbon; intvx; flotter pi ; fichier.getline(buff, sizeof(buff)); fichier >> vx >> pi :

La méthode getline lira la première ligne du fichier jusqu'à la fin et l'opérateur >> attribuera des valeurs aux variables.

L'exemple suivant montre l'ajout de données à un fichier texte, puis la lecture de l'intégralité du fichier. Une boucle while(1) est utilisée à la place de while(!file2.eof()) pour les raisons évoquées dans .

#inclure #inclure en utilisant l'espace de noms std ; int main() ( fichier ofstream; file.open("test.txt",ios::out|ios::app); if (!file) ( cout<< "File error - can"t open to write data!"; cin.sync(); cin.get(); return 1; } for (int i=0; i<10; i++) file << i << endl; file.close(); ifstream file2; file2.open("test.txt", ios::in); if (!file2) { cout << "File error - can"t open to read data!"; cin.sync(); cin.get(); return 2; } int a,k=0; while (1) { file2 >>une ; if (file2.eof()) break; cout<< a << " "; k++; } cout << endl << "K=" << k << endl; file2.close(); cin.sync(); cin.get(); return 0; }

L'exemple suivant montre une boucle qui lit les lignes du fichier test.txt et les affiche sur la console.

#inclure #inclure en utilisant l'espace de noms std ; int main() ( ifstream file; // crée un fichier objet stream file.open("test.txt"); // ouvre le fichier en lecture if (!file) return 1; // retourne à l'erreur d'ouverture char str; // Tampon de ligne statique // Lit et affiche les lignes dans une boucle jusqu'à eof while (!file.getline(str, sizeof(str)).eof()) cout<< str << endl; // вывод прочитанной строки на экран cin.sync(); cin.get(); return 0; }

Ce code sous Windows dépend également de la présence d'un caractère de nouvelle ligne dans la dernière ligne du fichier ; il serait plus fiable de faire ceci :

While (1) ( if (file.eof()) break; file.getline(str, sizeof(str)); cout<< str << endl; }

Les appels explicites aux méthodes open et close ne sont pas requis. En effet, appeler le constructeur avec un argument permet d'ouvrir le fichier immédiatement, au moment de la création de l'objet fichier threadé :

Fichier Ifstream("test.txt");

Au lieu de la méthode close, vous pouvez utiliser l'opérateur delete, qui appellera automatiquement le destructeur de l'objet fichier et fermera le fichier. Le code de la boucle while garantit des vérifications appropriées de fin de fichier.

classe ofstream : écriture de fichiers

La classe ofstream est conçue pour générer des données à partir d'un flux de fichiers. Ce qui suit répertorie les principales méthodes de cette classe.

L'opérateur d'inclusion décrit précédemment est pratique pour organiser l'écriture dans un fichier texte :

Fichier Ofstream("temp.txt"); si (!fichier) retourne ; pour (int je=1; je<=3; i++) file << "Строка " << i << endl; file.close();

Fichiers binaires

En principe, les données binaires sont traitées comme des données texte. La différence est que si les données binaires sont écrites dans une structure logique spécifique, elles doivent alors être lues à partir d'un fichier dans une variable du même type de structure.

Le premier paramètre des méthodes d'écriture et de lecture (l'adresse du bloc d'écriture/lecture) doit être du type pointeur de caractère char * , il est donc nécessaire d'effectuer une conversion explicite du type d'adresse de la structure void *. Le deuxième paramètre spécifie que les blocs binaires du fichier ont une taille d'octet constante quelle que soit la longueur réelle de l'enregistrement. L'application suivante fournit un exemple de création et d'affichage de données dans un simple bloc-notes. Les entrées du fichier sont ensuite lues séquentiellement et affichées sur la console.

#inclure #inclure #inclure en utilisant l'espace de noms std ; struct Notes ( // structure de données du notebook char Name; // nom complet char Phone; // phone int Age; // age ); int main() ( setlocale(LC_ALL, "Russe"); Notes Note1= ("Le Terrible Ioann Vasilyevich", "non installé", 60 ); Notes Note2= ("Godunov Boris Fedorovich", "095-111-2233" , 30 ); Notes Note3= ( "Romanov Petr Mikhailovich ", "812-333-2211 ", 20 ); ofstream ofile("Notebook.dat", ios::binary); ofile.write((char*)&Note1, sizeof (Notes)); // 1er bloc ofile.write((char*)&Note2, sizeof(Notes)); // 2ème bloc ofile.write((char*)&Note3, sizeof(Notes)); / / 3ème bloc ofile.close(); // ferme le fichier enregistré ifstream ifile("Notebook.dat", ios::binary); Notes Note; // variable structurée char str; // tampon de chaîne statique // Lit et affiche les lignes dans un boucle jusqu'à eof while (!ifile.read((char*)&Note, sizeof(Notes)).eof()) ( sprintf(str, "%s\tPhone: %s\tAge: %d" , Note.Name, Note.Téléphone, Note.Age); cout<< str << endl; } ifile.close(); // закрыть прочитанный файл cin.sync(); cin.get(); return 0; }

À la suite de l'exécution de ce code, un fichier binaire Notebook.dat est formé de trois blocs de 80 octets chacun (en supposant que les caractères sont à un seul octet). Naturellement, vous pouvez utiliser d'autres méthodes de threading et effectuer n'importe quelle opération sur les champs d'une structure de données spécifique.

Classe fstream : accès aléatoire aux fichiers

Supposons que nous ayons 100 entrées dans notre cahier et que nous souhaitions compter la 50ème. Bien sûr, vous pouvez organiser une boucle et lire tous les enregistrements du premier au suivant. Évidemment, une solution plus ciblée consiste à définir le pointeur de position du fichier pos directement sur l'entrée 50 et à y lire :

Ifstream ifile("Notebook.dat", ios::binary); int pos = 49 * sizeof(Notes); ifile.seekg(pos); // recherche la 50ème entrée Notes Note ; //Notes – la structure « enregistrement » décrite ci-dessus ifile.read((char*)&Note, sizeof(Notes));

De telles opérations de recherche sont efficaces si le fichier est constitué d'enregistrements de taille connue et constante. Pour remplacer le contenu d'un enregistrement arbitraire, vous devez ouvrir le flux de sortie en mode modification :

Ofstream ofile ("Notebook.dat", ios::binary | ios::ate); int pos = 49 * sizeof(Notes); ofile seekp(pos); // recherche de la 50e note Notes Note50 = ("Eltsine Boris Nikolaïevitch", "095-222-3322", 64); ofile.write((char*)&Note, sizeof(Notes)); // remplacement

Si vous ne spécifiez pas le drapeau ios::ate (ou ios::app), alors lorsque vous ouvrirez le fichier binaire Notebook.dat, son contenu précédent sera effacé !

Enfin, il est possible d'ouvrir un fichier simultanément en lecture/écriture, en utilisant les méthodes héritées par la classe streaming fstream de ses prédécesseurs. Puisque la classe fstream est dérivée de istream et ostream (respectivement parents de ifstream et ofstream), toutes les méthodes mentionnées précédemment deviennent disponibles dans l'application.

L'exemple suivant montre le réarrangement des première et troisième entrées du fichier Notebook.dat.

#inclure #inclure #inclure en utilisant l'espace de noms std ; struct Notes (nom du caractère ; char Téléphone ; int Âge ; ); int main() ( setlocale(LC_ALL, "Russe"); Notes Note1, Note3; // Ouvrir le fichier pour lire/écrire simultanément fstream file("Notebook.dat", ios::binary | ios::in | ios: : out); file.seekg(2 * sizeof(Notes)); // recherche et lit Note3 file.read((char*)&Note3, sizeof(Notes)); file.seekg(0); // recherche et lecture Note1 file.read((char*)&Note1, sizeof(Notes)); file.seekg(0); // Note1<== Note3 file.write((char*)&Note3, sizeof(Notes)); file.seekg(2 * sizeof(Notes)); // Note3 <== Note1 file.write((char*)&Note1, sizeof(Notes)); char str; // Считывать и отображать записи в цикле, пока не eof file.seekg(0); // вернуться к началу файла while (!file.read((char*)&Note1, sizeof(Notes)).eof()) { sprintf(str, "%s\tТел: %s\tВозраст: %d", Note1.Name, Note1.Phone, Note1.Age); cout << str << endl; } file.close(); cin.sync(); cin.get(); return 0; }

Dans le constructeur de l'objet fichier, vous devez spécifier les indicateurs ios::in et ios::out, permettant des opérations de lecture et d'écriture simultanées. Suite à l'exécution de ce code, les première et troisième entrées du fichier binaire Notebook.dat seront échangées.

Il existe des exemples supplémentaires sur le sujet.

Nous avons déjà appris à écrire des informations dans un fichier texte. – Si vous n’avez pas appris comment faire, consultez l’article précédent. C'est raconté et décrit en détail

Mais que se passe-t-il si le fichier existe déjà et que nous devons en lire des informations pour les traiter ? Heureusement, c'est aussi assez simple. Permettez-moi de vous rappeler qu'il existe plusieurs options pour mettre en œuvre cette tâche, je n'en ai décrit qu'une seule. Celui décrit est celui qui, pour une raison quelconque, me semble personnellement le plus simple à comprendre.

#inclure

int main()
{
caractère s1 //La variable lira la chaîne
ifstream dans (« C:\\\FromC\\myfile.txt » ); //Ouvrez le fichier pour lire les informations
dans >>s1 ; //lire la ligne
in.close() // Fermeture du dossier

cout<Afficher la valeur s1à l'écran
renvoie 0 ;
}

Voici le programme le plus simple pour lire la première ligne d'un fichier texte situé le long du chemin
C:\\\FromC\\monfichier.txt –
Puisqu'il s'agit d'une continuation de l'article précédent, j'ai décidé d'utiliser le fichier que nous y avons créé. Cela ne devrait probablement pas poser de difficultés.
Mais revenons au code. Nous ouvrons d’abord le fichier pour en lire les informations, pour cela nous utilisons la commande ifstream entre parenthèses, nous indiquons soit le nom du fichier, soit le chemin d'accès au fichier, comme je l'ai fait. (« C:\\\FromC\\monfichier.txt » );
Lorsque nous ouvrions un fichier pour en lire quelque chose, nous déclarions une variable comme char –
caractère s1
Il ne nous reste plus qu'à attribuer à la variable la valeur de la chaîne du fichier. Nous faisons cela en équipe dans
Faites attention aux équerres dans >>
En fait, comme cela devrait ressortir des commentaires sur le code du programme, pour que la variable attribue la valeur lue, nous devons l'écrire après dans >>
dans >>s1 ;

Cela ne semble pas être une tâche particulièrement difficile, surtout si vous maîtrisez déjà parfaitement et avez appris à utiliser le matériel de l'article précédent - tout est absolument pareil, seules 2 commandes sont différentes

Créer un fichier et y écrire des informations C++

de flux dehors ( Nom de fichier );
dehors<< (Chaîne à écrire);
dehors.fermer();
=============================

Lire le texte d'un fichier et imprimer le texte à l'écran en C++

ifstream dans (Nom de fichier );
dans>> (Lire la ligne);
dans.fermer();(Fermez le fichier)
============================
Écrivons un programme simple qui lira le texte saisi au clavier et l'écrira dans un fichier :

#inclure
#inclure

int main()
{
\\ 3 futures lignes
clrscsr(); // Effacer l'écran

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

/*Commence à travailler avec le fichier*/
ofstream out (« C:\\\FromC\\myfile.txt » ); //Ouvrir un fichier en écriture
dehors<Écrivez la première ligne
dehors<Écrivez la deuxième ligne
dehors<Écrivez la troisième ligne
out.close(); // Fermeture du dossier

//Réinitialiser les variables

pour (int je =0 ;je<=255 ;i ++)
(a =*"" ; b =*"" ; c =*"" ;)


ifstream dans (« C:\\\FromC\\monfichier.txt » );
dans >>a >>b >>c ; //Nous lisons chaque nouvelle ligne dans une nouvelle variable
joindre(); // Fermeture du dossier

/* */

pour (i =0 ;a !=*“” ;i ++)
{
si (i >sizeof(a )) casser ;
cout<

}
cout<<“\n” ; \\

/* */


{
si (i > taille de (b)) casser ;
cout<
}
cout<<“\n” ; \\ Déplacement du curseur vers une nouvelle ligne

/* */

pour (i =0 ;с !=*“” ;i ++)
{
si (i >sizeof(c )) casser ;
cout<<с ;
}

renvoie 0 ;
}
===================

Dans les exemples ci-dessus, il y en a un ÉNORME défaut. Si nous essayons de saisir une ligne contenant des espaces, le programme ne fonctionnera pas comme nous le souhaitons. Probablement, non seulement moi, mais aussi de nombreuses autres personnes ont rencontré cette erreur. Par conséquent, je laisse le code incorrect afin que vous puissiez voir ce que vous pourriez rencontrer.

Comme il n'y a pas de livres à la maison, j'ai recommencé à parcourir Internet et j'ai trouvé beaucoup de bêtises sophistiquées de toutes sortes. Mais d'une manière ou d'une autre, j'ai trouvé une solution à mon problème.
Ça m'a aidé de lire ça cout soutient ses méthodes. Et sur Internet tous les conseils vont vers l'utilisation de la fonction obtenir la ligne Heureusement pour moi, j'ai découvert très rapidement comment utiliser cette fonction et je l'ai ensuite utilisée dans le code.
En général, cela vaut la peine de mentionner et de décrire cette fonction, mais pour l'instant je ne la comprends pas vraiment, je comprends juste qu'elle doit être utilisée et je comprends comment, je vais donc donner un exemple plus correct de notre programme en cours de développement :

#inclure
#inclure

int main()
{
caractère a,b,c; \\ 3 futures lignes
clrscsr(); // Effacer l'écran

/* Saisir les valeurs des variables*/

cout<<“Wwedi pervuu stroku” ; cin.getline(a,sizeof(a)); fin ;
cout<<“Wwedi wtoruu stroku” ; cin.getline(a,sizeof(b)); fin ;
cout<<“Wwedi tretuu stroku” ; cin.getline(a,sizeof(c)); fin ;
clrscr(); //Après avoir entré les valeurs, l'écran a été effacé

/*Commence à travailler avec le fichier*/
ofstream out (« C:\\\FromC\\myfile.txt »); // Ouvrir un fichier en écriture
dehors<
Écrivez la première ligne
dehors<Écrivez la deuxième ligne
dehors<Écrivez la troisième ligne
out.close(); // Fermeture du dossier

//Réinitialiser les variables

pour (int je =0 ;je<=255 ;i ++)
(a =*"" ; b =*"" ; c=*"" ;)

/*Continuer à travailler avec le fichier*/

si diffuser dans (« C:\\\FromC\\monfichier.txt » );
in.getline(a,sizeof(a));// UN
in.getline(b,sizeof(b));// Lire une ligne dans une variable b
in.getline(c,sizeof(c)); // Lire une ligne dans une variable c
joindre(); // Fermeture du dossier

/* On lit la première ligne caractère par caractère et on l'affiche à l'écran */

pour (i =0 ;a !=*“” ;i++)
{
si (i >sizeof(a )) casser ;
cout<

}
cout<<“\n” ; \\ Déplacement du curseur vers une nouvelle ligne

/* On lit la deuxième ligne caractère par caractère et on l'affiche à l'écran */

pour (i =0 ;b !=*“” ;i ++)
{
si (i > taille de (b)) casser ;
cout<
}
cout<<“\n” ; \\ Déplacement du curseur vers une nouvelle ligne

/* On lit la troisième ligne caractère par caractère et on l'affiche à l'écran */

pour (i =0 ;с !=*“” ;i++)
{
si (i>taille de (c )) casser ;
cout<<с[i];
}

getch(); \\En attente que la touche Entrée soit enfoncée
renvoie 0 ;
}
===================

Ce document décrit un exemple de lecture d'informations caractère par caractère. Puisque je n'ai pas décrit le travail avec des variables comme carboniser, les débutants peuvent rencontrer des difficultés à comprendre le code. Je ne savais juste pas quel type carboniser a quelques particularités et j'ai pensé que tout était plus simple. Par conséquent, certains moments incompréhensibles du programme ci-dessus peuvent être lus dans l'article suivant travailler avec des caractères V C++ pour les débutants

Sinon, l'exemple donné sur la façon de lire les lignes d'un fichier texte en C++ devrait être accessible et tout à fait compréhensible. Ce n'est pas l'option de mise en œuvre optimale pour le moment, et j'ai raté certains points importants, mais puisque nous commençons à apprendre le langage C++, cela suffit pour l'instant. Plus tard, j'atteindrai probablement ce qui m'a manqué, mais maintenant je n'ai besoin de percevoir que le plus nécessaire.

Si vous et moi comprenons ce document, cela signifie que nous avons fait un petit pas vers notre professionnalisme.

Note:
casser ;– C'est la commande qui sort de la boucle. Nous avons si le compteur de cycles pour devient plus grand que la taille déclarée de la variable carboniser, puis on sort de force de la boucle
!= – C'est la condition que nous avons posée. Cette condition est notée par l'inégalité
si(a !=b )– Se lit comme si un inégal b

fin ; – Cela déplace le curseur vers une nouvelle ligne à l'intérieur de la console (pour autant que je sache)
Cette commande est similaire à "\n"

Travailler avec des fichiers texte en C++.

Il existe deux principaux types de fichiers : texte et binaire. Les fichiers permettent à l'utilisateur de lire de grandes quantités de données directement à partir du disque sans avoir à les saisir au clavier.

    Texte les fichiers composés de n'importe quel caractère sont appelés. Ils sont organisés en lignes, chacune se terminant par un caractère de fin de ligne. La fin du fichier lui-même est indiquée par le symbole « fin de fichier ». Lors de l'écriture d'informations dans un fichier texte, qui peut être visualisé à l'aide de n'importe quel éditeur de texte, toutes les données sont converties en type de caractères et stockées sous forme de caractères.

    DANS binaire Dans les fichiers, les informations sont lues et écrites sous forme de blocs d'une certaine taille, dans lesquels des données de tout type et de toute structure peuvent être stockées.

Pour travailler avec des fichiers, spécial Types de données, appelé ruisseaux. Couler ifstream est utilisé pour travailler avec des fichiers en mode lecture, et de flux en mode enregistrement. Pour travailler avec des fichiers en mode écriture et lecture, un flux est utilisé fstream.

Dans les programmes C++, lorsque vous travaillez avec des fichiers texte, vous devez inclure les bibliothèques iostream et fstream.

Pour écrire données dans un fichier texte, vous avez besoin de :

    décrire une variable de type ofstream.

    afficher les informations dans un fichier.

    assurez-vous de fermer le fichier.

Pour en lisant les données d'un fichier texte, vous avez besoin de :

    décrire une variable de type ifstream.

    ouvrez un fichier à l'aide de la fonction open.

    fermez le fichier.

Enregistrer informations dans un fichier texte

    Comme mentionné précédemment, pour commencer à travailler avec un fichier texte, vous devez définir une variable de type flux. Par exemple, comme ceci :

    Une variable F sera créée pour écrire des informations dans le fichier.

    A l'étape suivante, le fichier doit être ouvert en écriture. En général, l'opérateur d'ouverture de flux ressemblera à :

F.open("fichier", mode);

Ici F est une variable décrite comme ofstream,

fichier - nom complet du fichier sur le disque,

mode - mode de travail avec le fichier en cours d'ouverture.

Veuillez noter que lorsque vous spécifiez le nom complet du fichier, vous devez utiliser une double barre oblique. Par exemple, le nom complet du fichier noobs.txt, situé dans le dossier du jeu sur le lecteur D :, devra être écrit comme ceci :

D:\\jeu\\noobs.txt.

Le fichier peut être ouvert dans l'un des modes suivants :

ios::in - ouvre le fichier en mode lecture de données, ce mode est le mode par défaut pour ifstreams ;

ios::out - ouvre un fichier en mode écriture de données (dans ce cas, les informations sur le fichier existant sont détruites), ce mode est le mode par défaut pour ofstreams ;

ios::app - ouvre le fichier en mode d'écriture des données jusqu'à la fin du fichier ;

ios::ate - passer à la fin d'un fichier déjà ouvert ;

ios::trunc - efface le fichier, cela se produit également en mode ios::out ;

ios::nocreate - n'ouvre pas un fichier s'il n'existe pas ;

ios::noreplace - n'ouvre pas un fichier existant.

Le paramètre mode peut être absent, auquel cas le fichier est ouvert dans le mode par défaut pour ce flux.

Après une ouverture réussie du fichier (dans n'importe quel mode), la variable F stockera vrai, sinon faux. Cela vous permettra de vérifier l'exactitude de l'opération d'ouverture du fichier.

Vous pouvez ouvrir un fichier (prenons comme exemple le fichier D:\\game\\noobs.txt) en mode enregistrement de l'une des manières suivantes :

// d'abord chemin

du flux F ;

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

//deuxième méthode, le mode ios::out est le mode par défaut

// Pour coulerde flux

du flux F ;

//la troisième méthode combine la description de la variable et le type du flux

// et ouverture du fichier en une seule instruction

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

Après avoir ouvert le fichier en mode écriture, un fichier vide sera créé dans lequel vous pourrez écrire des informations.

Si vous souhaitez ouvrir un fichier existant en mode écriture en premier, vous devez utiliser ios::app comme mode.

Après avoir ouvert un fichier en mode enregistrement, vous pouvez y écrire de la même manière que sur l'écran, uniquement à la place du périphérique de sortie standardcoutvous devez préciser le nom du fichier ouvert.

Par exemple, pour écrire la variable a dans le flux F, l'instruction de sortie ressemblera à :

Pour une sortie séquentielle vers le flux G des variables b, c, d, l'opérateur de sortie deviendra comme ceci :

g<

La fermeture d'un flux se fait à l'aide de l'opérateur :

EXEMPLE:

Créez un fichier texte D:\\game\\noobs.txt et écrivez-y n nombres réels.

#include "stdafx.h"

#inclure

#inclure

#inclure

en utilisant l'espace de noms std ;

int main()

setlocale(LC_ALL, "RUS");

int je, n;

Double A;

//décrit un flux pour écrire des données dans un fichier

de flux F;

//ouvre le fichier en mode écriture,

//modeiOS:: dehorsinstallé par défaut

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

//entre le nombre de nombres réels

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

//boucle pour saisir des nombres réels

// et les écris dans un fichier

pour (i=0; je

cout<<"a=";

//entre un numéro

cin>>a;

F<

//ferme le flux

f.close();

système("pause");

renvoie 0 ;

_______________________________________________________________

Afin de lire les informations d'un fichier texte, vous devez décrire une variable comme ifstream. Après cela, vous devez ouvrir le fichier pour le lire à l'aide de l'opérateur ouvrir. Si la variable s'appelle F, alors les deux premières instructions ressembleront à ceci :

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

Après avoir ouvert un fichier en mode lecture, vous pouvez en lire les informations de la même manière qu'à partir du clavier, uniquement au lieu decinspécifiez le nom du flux à partir duquel les données seront lues.

Par exemple, pour lire le flux F dans la variable a, l'instruction d'entrée ressemblerait à ceci :

Deux nombres dans un éditeur de texte sont considérés comme séparés s'il y a au moins un des caractères entre eux : espace, tabulation, fin de ligne. C'est bien si le programmeur sait à l'avance combien et quelles valeurs stocker dans le fichier texte. Cependant, souvent le type de valeurs stockées dans le fichier est simplement connu, mais leur nombre peut varier. Pour résoudre ce problème, vous devez lire les valeurs du fichier une par une et avant chaque lecture, vérifier si la fin du fichier a été atteinte. Il y a une fonction pour ça F. eof().

Ici F est le nom du thread, la fonction renvoie une valeur booléenne : vrai ou faux, selon que la fin du fichier est atteinte. Par conséquent, une boucle pour lire le contenu du fichier entier peut être écrite comme ceci :

//organiser la lecture des valeurs d'un fichier, exécution

//la boucle se brisera lorsque nous arriverons à la fin du fichier,

//dans ce cas, F.eof() retournera true

tandis que (!F.eof())

EXEMPLE:

Le fichier texte D:\\game\\noobs.txt stocke les nombres réels, les affiche à l'écran et calcule leur nombre.

#include "stdafx.h"

#inclure

#inclure

#inclure

#inclure

en utilisant l'espace de noms std ;

int main()

setlocale(LC_ALL, "RUS");

entier n=0 ;

flotter un;

fstream F ;

//ouvre le fichier en mode lecture

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

//si le fichier a été ouvert correctement, alors

//boucle pour lire les valeurs d'un fichier ; l'exécution de la boucle sera interrompue,

//quand on atteint la fin du fichier, dans ce cas F.eof() retournera true.

tandis que (!F.eof())

//lecture de la valeur suivante du flux F dans la variable a

F>>a ;

//afficher la valeur de la variable a à l'écran

cout<

//augmenter le nombre de nombres lus

//ferme le flux

F.close();

//saisir à l'écran le nombre de nombres lus

cout<<"n="<

//si l'ouverture du fichier était incorrecte, alors la sortie

//messages sur l'absence d'un tel fichier

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

système("pause");

renvoie 0 ;

C++. Traitement des fichiers binaires

Lors de l'écriture d'informations dans un fichier binaire, les caractères et les nombres sont écrits sous forme de séquence d'octets.

Pour écrire données dans un fichier binaire, vous avez besoin de :

    décrire une variable de fichier de type FAIL * à l'aide de l'opérateur FILE *filename;. Ici, le nom de fichier est le nom de la variable où le pointeur vers le fichier sera stocké.

    écrire des informations dans un fichier à l'aide de la fonction fwrite

Pour compter b données provenant d'un fichier binaire, il vous faut :

    décrire une variable de type FILE *

    ouvrir un fichier en utilisant la fonction fopen

    fermer un fichier en utilisant la fonction fclose

Fonctions de base requises pour travailler avec des fichiers binaires.

Pour découvertes Le fichier est destiné à la fonction fopen.

FICHIER *fopen(const *nom de fichier, const char *mode)

Ici, filename est une chaîne qui stocke le nom complet du fichier en cours d'ouverture, mode est une chaîne qui détermine le mode de travail avec le fichier ; les valeurs suivantes sont possibles :

"rb" - ouvre le fichier binaire en mode lecture ;

« wb » - crée un fichier binaire pour l'enregistrement ; s'il existe, son contenu est effacé ;

"ab" - crée ou ouvre un fichier binaire à ajouter à la fin du fichier ;

« rb+ » - ouvre un fichier binaire existant en mode lecture-écriture ;

« wb+ » - ouvrez le fichier binaire en mode lecture-écriture, le fichier existant est effacé ;

"ab+" - un fichier binaire est ouvert ou créé pour corriger les informations existantes et ajouter de nouvelles informations à la fin du fichier.

La fonction renvoie NULL dans la variable de fichier f si le fichier ne s'ouvre pas. Après ouverture d'un fichier, son 0ème octet est disponible, le pointeur de fichier est 0 dont la valeur, au fur et à mesure de sa lecture ou de son écriture, est décalée du nombre d'octets lus (écrits). La valeur actuelle du pointeur de fichier est le numéro d'octet à partir duquel l'opération de lecture ou d'écriture aura lieu.

Pour fermeture le fichier est destiné à la fonction fclose

int fclose(FILE *nom de fichier);

Renvoie 0 si le fichier a été fermé avec succès, NULL sinon.

La fonction de suppression est pour suppression des dossiers.

int supprimer (const char *nom de fichier);

Cette fonction supprime un fichier nommé filenema du disque. Le fichier à supprimer doit être fermé. La fonction renvoie une valeur non nulle si le fichier n'a pas pu être supprimé.

Pour renommer fichiers, la fonction renommer est destinée à :

int rename(const char *ancien nom de fichier, const char *nouveau nom de fichier);

Le premier paramètre est l'ancien nom du fichier, le second est le nouveau. Renvoie 0 si le programme se termine avec succès.

En lisantà partir d'un fichier binaire se fait à l'aide de la fonction fread :

fread(void *ptr, taille, n, FILE *nom de fichier);

La fonction fread lit n éléments de taille taille du fichier nom de fichier dans un tableau ptr. La fonction renvoie le nombre d'éléments lus. Après la lecture d'un fichier, son pointeur est décalé de n*size octets.

Enregistrer vers un fichier binaire se fait à l'aide de la fonction fwrite :

fwrite(const void *ptr, taille, n, FILE *nom de fichier);

La fonction fwrite écrit dans le fichier filename à partir d'un tableau ptr de n éléments de taille size. La fonction renvoie le nombre d'éléments écrits. Après avoir écrit les informations dans le fichier, le pointeur est décalé de n*size octets.

Pour contrôle de fin de fichier il existe une fonction feof :

int feof(FILE *nom de fichier);

Il renvoie une valeur non nulle si la fin du fichier est atteinte.

EXEMPLE:

Créez un fichier binaire D:\\game\\noobs.dat et écrivez-y n nombres entiers et n nombres réels.

#include "stdafx.h"

#inclure

en utilisant l'espace de noms std ;

int main()

setlocale(LC_ALL, "RUS");

int n, je;

Double A;

//crée un fichier binaire en mode écriture

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

// saisir Nombresn

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

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

//boucle pour saisir n nombres réels

pour (i=0; je

//entre le prochain nombre réel

cout<<"a=";

cin>>a;

// écriture d'un nombre réel dans un fichier binaire

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

// fermer déposer

ffermer(f);

système("pause");

renvoie 0 ;

EXEMPLE:

Afficher le contenu du fichier binaire D:\\game\\noobs.dat créé lors de la tâche précédente

#include "stdafx.h"

#inclure

en utilisant l'espace de noms std ;

int main()

setlocale(LC_ALL, "RUS");

int n, je;

Double A;

FICHIER *f; //décrit la variable du fichier

//ouvre le fichier binaire existant en mode lecture

// lit un entier du fichier dans la variable n

//sortie n à l'écran

cout<<"n="<

// allouer de la mémoire pour un tableau de n nombres

a=nouveau double[n] ;

//lire n nombres réels du fichier dans le tableau a

// affiche le tableau à l'écran

pour (i=0; je

cout<

cout<

// fermer déposer

ffermer(f);

système("pause");

renvoie 0 ;

Fichier binaire- structure de données séquentielle, après ouverture d'un fichier, le premier octet qui y est stocké est disponible. Vous pouvez écrire ou lire les données d'un fichier de manière séquentielle. Disons que vous devez compter le quinzième nombre, puis le premier. En utilisant l'accès séquentiel, cela peut être fait de la manière suivante :

int n, je;

Double A;

FICHIER *f;

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

pour (i=0; je<15; i++)

ffermer(f);

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

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

ffermer(f);

Comme vous pouvez le constater, lire les nombres d’un fichier, puis rouvrir le fichier n’est pas le moyen le plus pratique. Il sera beaucoup plus pratique d'utiliser la fonction fseek pour déplacer le pointeur de fichier vers un octet donné.

int fseek(FILE *nom de fichier, décalage int long, origine int);

La fonction définit le pointeur de position actuel du fichier F conformément aux valeurs d'origine et de décalage. Le paramètre offset est égal au nombre d'octets dont le pointeur de fichier sera décalé par rapport à l'origine spécifiée par le paramètre origin. La valeur du paramètre origin doit être l'une des valeurs de décalage suivantes définies dans l'en-tête stdio.h :

SEEK_SET - depuis le début du fichier ;

SEEK_CUR - à partir de la position actuelle ;

SEEK_END - à partir de la fin du fichier.

La fonction renvoie une valeur nulle si l'opération a réussi, une valeur non nulle si le décalage a échoué.

La fonction fseek implémente en fait un accès direct à n'importe quelle valeur d'un fichier. Il vous suffit de connaître l'emplacement (numéro d'octet) de la valeur dans le fichier. Examinons l'utilisation de l'accès direct dans les fichiers binaires en utilisant le problème suivant comme exemple.

EXEMPLE

Dans le fichier binaire D:\\game\\noobs.dat créé précédemment, échangez les nombres réels les plus grands et les plus petits.

L'algorithme de résolution du problème comprend les étapes suivantes :

    lire les réels d'un fichier dans le tableau a.

    recherchez dans le tableau a les valeurs maximale (max) et minimale (min) et leurs nombres (imax, imin).

    déplacer le pointeur de fichier vers la valeur maximale et écrire min.

    déplacer le pointeur de fichier vers la valeur minimale et écrire max.

Vous trouverez ci-dessous le texte du programme pour résoudre le problème avec des commentaires.

#include "stdafx.h"

#inclure

en utilisant l'espace de noms std ;

int main()

setlocale(LC_ALL, "RUS");

int n, je, imax, imin ;

double *a, max, min ;

FICHIER *f;

//ouvre un fichier en mode lecture-écriture

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

//lire le numéro du fichier dans la variable n

// nombres réels dans le fichier

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

cout<<"n="<

// alloue de la mémoire pour stocker les nombres réels,

//qui sera stocké dans le tableau a

a=nouveau double[n] ;

//lire du fichier dans un tableau et des nombres réels

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

//recherche des éléments maximum et minimum

//dans le tableau a et leurs indices

pour (imax=imin=0, max=min=a, i=1; je

si (a[i]>max)

max=a[je];

si (un[je]

min=a[je];

// en mouvement aiguille À maximum élément

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

//écrit le min au lieu du maximum de l'élément de fichier

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

// en mouvement aiguille À le minimum élément

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

//enregistre le maximum au lieu de l'élément de fichier minimum

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

//fermeture du fichier

ffermer(f);

//libération de mémoire

supprimer [ ]un;

système("pause");

Mots clés: Fichiers texte, fopen, fclose, feof, setbuf, setvbuf, fflush, fgetc, fprintf, fscanf, fgets, flux tamponné, flux non tamponné.

Travailler avec des fichiers texte

Travailler avec un fichier texte est similaire à travailler avec la console : en utilisant des fonctions d'entrée formatées, nous enregistrons les données dans un fichier, en utilisant des fonctions de sortie formatées, nous lisons les données d'un fichier. Il existe de nombreuses nuances que nous examinerons plus tard. Les principales opérations à effectuer sont

  • 1. Ouvrez le fichier pour pouvoir y accéder. En conséquence, vous pouvez l'ouvrir pour lire, écrire, lire et écrire, réécrire ou écrire jusqu'à la fin du fichier, etc. Lorsque vous ouvrez un fichier, de nombreuses erreurs peuvent également se produire : le fichier peut ne pas exister, il peut s'agir d'un type de fichier incorrect, vous n'êtes peut-être pas autorisé à travailler avec le fichier, etc. Tout cela doit être pris en compte.
  • 2. Travailler directement avec le fichier - écriture et lecture. Ici, nous devons également nous rappeler que nous ne travaillons pas avec de la mémoire vive, mais avec un flux tamponné, qui ajoute ses propres spécificités.
  • 3. Fermez le fichier. Puisque le fichier est une ressource externe au programme, s'il n'est pas fermé, il continuera à rester en mémoire, éventuellement même après la fermeture du programme (par exemple, il ne sera pas possible de supprimer un fichier ouvert ou d'apporter des modifications, etc.). De plus, il est parfois nécessaire non pas de fermer, mais de « rouvrir » un fichier pour, par exemple, changer le mode d'accès.

De plus, il existe un certain nombre de tâches pour lesquelles nous n'avons pas besoin d'accéder au contenu du fichier : renommer, déplacer, copier, etc. Malheureusement, le standard C ne contient pas de description des fonctions répondant à ces besoins. Ils sont bien entendu disponibles pour chacune des implémentations du compilateur. Lire le contenu d'un répertoire (dossier, répertoire), c'est aussi accéder à un fichier, car le dossier lui-même est un fichier avec des métainformations.

Parfois, il est nécessaire d'effectuer certaines opérations auxiliaires : se déplacer à l'emplacement souhaité dans le fichier, mémoriser la position actuelle, déterminer la longueur du fichier, etc.

Pour travailler avec un fichier, vous avez besoin d'un objet FILE. Cet objet stocke l'identifiant du flux de fichiers et les informations nécessaires à sa gestion, notamment un pointeur vers son tampon, un indicateur de position de fichier et des indicateurs d'état.

L'objet FILE est lui-même une structure, mais ses champs ne sont pas accessibles. Le programme portable doit traiter le fichier comme un objet abstrait permettant d'accéder au flux de fichiers.

La création et l'allocation de mémoire pour un objet de type FILE s'effectuent à l'aide de la fonction fopen ou tmpfile (il en existe d'autres, mais nous nous concentrerons uniquement sur celles-ci).

La fonction fopen ouvre un fichier. Il reçoit deux arguments : une chaîne avec l'adresse du fichier et une chaîne avec le mode d'accès au fichier. Le nom du fichier peut être absolu ou relatif. fopen renvoie un pointeur vers un objet FILE qui peut être utilisé pour accéder davantage au fichier.

FILE* fopen(const char* nom de fichier, const char* mode);

Par exemple, ouvrons un fichier et écrivons-y Hello World

#inclure #inclure #inclure void main() ( //En utilisant la variable file, nous accéderons au fichier FILE *file; //Ouvre un fichier texte avec les autorisations d'écriture file = fopen("C:/c/test.txt", "w+t") ; //Écrire dans le fichier fprintf(file, "Hello, World!"); //Fermer le fichier fclose(file); getch(); )

La fonction fopen alloue elle-même de la mémoire pour l'objet, le nettoyage est effectué par la fonction fclose. Il est nécessaire de fermer le fichier, il ne se fermera pas tout seul.

La fonction fopen peut ouvrir un fichier en mode texte ou binaire. La valeur par défaut est le texte. Le mode d'accès peut être le suivant

Options d'accès aux fichiers.
Taper Description
r En lisant. Le fichier doit exister.
w Écrivez un nouveau fichier. Si un fichier du même nom existe déjà, son contenu sera perdu.
un Écrivez à la fin du fichier. Les opérations de positionnement (fseek, fsetpos, frewind) sont ignorées. Le fichier est créé s'il n'existait pas.
r+ Lecture et mise à jour. Vous pouvez à la fois lire et écrire. Le fichier doit exister.
w+ Enregistrement et mise à jour. Un nouveau fichier est créé. Si un fichier du même nom existe déjà, son contenu sera perdu. Vous pouvez à la fois écrire et lire.
un+ Fin du message et mise à jour. Les opérations de positionnement sont en lecture seule et ignorées pour les écritures. Si le fichier n'existait pas, un nouveau sera créé.

S'il est nécessaire d'ouvrir le fichier en mode binaire, alors la lettre b est ajoutée à la fin de la ligne, par exemple « rb », « wb », « ab », ou, pour le mode mixte, « ab+ », « wb+", "ab+". Au lieu de b, vous pouvez ajouter la lettre t, le fichier s'ouvrira alors en mode texte. Cela dépend de la mise en œuvre. Dans la nouvelle norme C (2011), la lettre x signifie que fopen devrait échouer si le fichier existe déjà. Complétons notre ancien programme : rouvrez le fichier et considérez ce que nous y avons écrit.

#inclure #inclure #inclure 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(); )

Au lieu de la fonction fgets, vous pouvez utiliser fscanf, mais vous devez vous rappeler qu'elle ne peut lire la ligne que jusqu'au premier espace.
fscanf(fichier, "%127s", tampon);

De plus, au lieu d'ouvrir et de fermer un fichier, vous pouvez utiliser la fonction freopen, qui « rouvre » le fichier avec de nouveaux droits d'accès.

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

Les fonctions fprintf et fscanf diffèrent de printf et scanf uniquement en ce qu'elles prennent comme premier argument un pointeur vers le FILE vers lequel elles vont sortir ou à partir duquel elles vont lire des données. Il convient d'ajouter tout de suite que les fonctions printf et scanf peuvent être facilement remplacées par les fonctions fprintf et fscanf. Dans le système d'exploitation (nous considérons les systèmes d'exploitation les plus courants et les plus adéquats), il existe trois flux standard : le flux de sortie standard stdout, le flux d'entrée standard stdin et le flux de sortie d'erreur standard stderr. Ils s'ouvrent automatiquement au lancement de l'application et sont associés à la console. Exemple

#inclure #inclure #inclure void main() ( int a, b; fprintf(stdout, "Entrez deux nombres\n"); fscanf(stdin, "%d", &a); fscanf(stdin, "%d", &b); if (b == 0) ( fprintf(stderr, "Erreur : diviser par zéro"); ) else ( fprintf(stdout, "%.3f", (float) a / (float) b); ) getch(); )

Erreur lors de l'ouverture du fichier

Si l'appel de la fonction fopen échoue, il renverra NULL. Les erreurs lors du travail avec des fichiers se produisent assez souvent, donc chaque fois que nous ouvrons un fichier, nous devons vérifier le résultat du travail

#inclure #inclure #inclure #define ERROR_OPEN_FILE -3 void main() ( FILE *file; char buffer; file = fopen("C:/c/test.txt", "w"); if (file == NULL) ( printf("Erreur d'ouverture file"); getch(); exit(ERROR_OPEN_FILE); ) fprintf(file, "Hello, World!"); freopen("C:/c/test.txt", "r", file); if (file = = NULL) ( printf("Erreur d'ouverture du fichier"); getch(); exit(ERROR_OPEN_FILE); ) fgets(buffer, 127, file); printf("%s", buffer); fclose(file); getch() ; )

Le problème se pose lorsque plusieurs fichiers sont ouverts à la fois : si l'un d'entre eux ne peut pas être ouvert, alors les autres doivent également être fermés.

FICHIER *inputFile, *outputFile ; non signé m, n; non signé i, j; inputFile = fopen(INPUT_FILE, READ_ONLY); if (inputFile == NULL) ( printf("Erreur d'ouverture du fichier %s", INPUT_FILE); getch(); exit(3); ) outputFile = fopen(OUTPUT_FILE, WRITE_ONLY); if (outputFile == NULL) ( printf("Erreur d'ouverture du fichier %s", OUTPUT_FILE); getch(); if (inputFile != NULL) ( fclose(inputFile); ) exit(4); ) ...

Dans des cas simples, vous pouvez agir de front, comme dans le morceau de code précédent. Dans les cas plus complexes, on utilise des méthodes qui remplacent RAII du C++ : wrappers, ou fonctionnalités du compilateur (nettoyage dans GCC), etc.

Mise en mémoire tampon des données

Comme mentionné précédemment, lorsque nous produisons des données, elles sont d'abord placées dans un tampon. Le tampon est vidé

  • 1) S'il est plein
  • 2) Si le flux est fermé
  • 3) Si nous indiquons explicitement qu'il est nécessaire de vider le tampon (il y a aussi des exceptions ici :)).
  • 4) Également effacé si le programme s'est terminé avec succès. En même temps, tous les dossiers sont fermés. En cas d'erreur d'exécution, cela peut ne pas se produire.

Vous pouvez forcer le déchargement du tampon en appelant la fonction fflush(File *). Regardons deux exemples – avec et sans nettoyage.

#inclure #inclure #inclure 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(); )

Décommentez l'appel fflush. Au moment de l'exécution, ouvrez le fichier texte et examinez le comportement.

Vous pouvez attribuer vous-même un tampon de fichier en définissant votre propre taille. Cela se fait à l'aide de la fonction

Void setbuf(FILE * flux, char * tampon);

qui prend un FILE déjà ouvert et un pointeur vers un nouveau tampon. La taille du nouveau tampon ne doit pas être inférieure à BUFSIZ (par exemple, sur le poste de travail actuel, BUFSIZ est de 512 octets). Si vous transmettez NULL comme tampon, le flux n'est plus tamponné. Vous pouvez également utiliser la fonction

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

qui accepte un tampon de taille arbitraire. Le mode peut prendre les valeurs suivantes

  • _IOFBF- mise en mémoire tampon complète. Les données sont écrites dans le fichier lorsqu'il est plein. En lecture, le tampon est considéré comme plein lorsqu'une opération d'entrée est demandée et le tampon est vide.
  • _IOLBF- mise en mémoire tampon linéaire. Les données sont écrites dans le fichier lorsqu'il est plein ou lorsqu'un caractère de nouvelle ligne est rencontré. En lecture, le tampon est rempli jusqu'au caractère de nouvelle ligne lorsqu'une opération d'entrée est demandée et le tampon est vide.
  • _IONBF– pas de mise en mémoire tampon. Dans ce cas, les paramètres size et buffer sont ignorés.
En cas de succès, la fonction renvoie 0.

Exemple : définissons notre propre tampon et voyons comment s'effectue la lecture d'un fichier. Laissez le fichier être court (quelque chose comme Hello, World !), et nous le lisons caractère par caractère

#inclure #inclure #inclure 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); )

On voit que les données sont déjà dans le tampon. La lecture caractère par caractère se fait depuis le buffer.

feof

Fonction int feof(FILE * stream); renvoie vrai si la fin du fichier est atteinte. La fonction est pratique à utiliser lorsque vous devez parcourir l'intégralité du fichier du début à la fin. Soit un fichier avec du contenu textuel text.txt. Nous lisons le fichier caractère par caractère et l'affichons à l'écran.

#inclure #inclure #inclure void main() ( FILE *input = NULL; char c; input = fopen("D:/c/text.txt", "rt"); if (input == NULL) ( printf("Erreur d'ouverture du fichier") ; _getch(); exit(0); ) while (!feof(input)) ( c = fgetc(input); fprintf(stdout, "%c", c); ) fclose(input); _getch(); )

Tout irait bien, mais la fonction feof ne fonctionne pas correctement... Cela est dû au fait que la notion de « fin de fichier » n'est pas définie. Une erreur qui se produit souvent lors de l'utilisation de feof est que les dernières données lues sont imprimées deux fois. Cela est dû au fait que les données sont écrites dans le tampon d'entrée, la dernière lecture se produit avec une erreur et la fonction renvoie l'ancienne valeur lue.

#inclure #inclure #inclure void main() ( FILE *input = NULL; char c; input = fopen("D:/c/text.txt", "rt"); if (input == NULL) ( printf("Erreur d'ouverture du fichier") ; _getch(); exit(0); ) while (!feof(input)) ( fscanf(input, "%c", &c); fprintf(stdout, "%c", c); ) fclose(input); _getch(); )

Cet exemple échouera (très probablement) et imprimera deux fois le dernier caractère du fichier.

La solution n'est pas d'utiliser feof. Par exemple, stockez le nombre total d'enregistrements ou utilisez le fait que les fonctions fscanf etc. renvoient généralement le nombre de valeurs correctement lues et mises en correspondance.

#inclure #inclure #inclure void main() ( FILE *input = NULL; char c; input = fopen("D:/c/text.txt", "rt"); if (input == NULL) ( printf("Erreur d'ouverture du fichier") ; _getch(); exit(0); ) while (fscanf(input, "%c", &c) == 1) ( fprintf(stdout, "%c", c); ) fclose(input); _getch() ; )

Exemples

1. Un fichier contient deux nombres : les dimensions du tableau. Remplissons le deuxième fichier avec un tableau de nombres aléatoires.

#inclure #inclure #inclure #inclure //Noms de fichiers et autorisations #define INPUT_FILE "D:/c/input.txt" #define OUTPUT_FILE "D:/c/output.txt" #define READ_ONLY "r" #define WRITE_ONLY "w" //Valeur maximale pour le tableau size #define MAX_DIMENSION 100 //Erreur lors de l'ouverture du fichier #define ERROR_OPEN_FILE -3 void main() ( FILE *inputFile, *outputFile; non signé m, n; non signé i, j; inputFile = fopen(INPUT_FILE, READ_ONLY); if ( inputFile == NULL) ( printf("Erreur d'ouverture du fichier %s", INPUT_FILE); getch(); exit(ERROR_OPEN_FILE); ) outputFile = fopen(OUTPUT_FILE, WRITE_ONLY); if (outputFile == NULL) ( printf("Erreur ouverture du fichier %s", OUTPUT_FILE); getch(); //Si le fichier peut être ouvert en lecture, alors il doit être fermé if (inputFile != NULL) ( fclose(inputFile); ) exit(ERROR_OPEN_FILE); ) fscanf (inputFile, "%ud %ud", &m, &n); si (m > MAX_DIMENSION) ( m = MAX_DIMENSION; ) if (n > MAX_DIMENSION) ( n = MAX_DIMENSION; ) srand(time(NULL)); pour (i = 0 ; je< n; i++) { for (j = 0; j < m; j++) { fprintf(outputFile, "%8d ", rand()); } fprintf(outputFile, "\n"); } //Закрываем файлы fclose(inputFile); fclose(outputFile); }

2. L'utilisateur copie le fichier et sélectionne d'abord le mode de fonctionnement : le fichier peut être sorti sur la console ou copié dans un nouveau fichier.

#inclure #inclure #inclure #define ERROR_FILE_OPEN -3 void main() ( FILE *origin = NULL; FILE *output = NULL; char filename; int mode; printf("Entrez le nom de fichier: "); scanf("%1023s", nom de fichier); origin = fopen (nom de fichier, "r"); if (origine == NULL) ( printf("Erreur d'ouverture du fichier %s", nom de fichier); getch(); exit(ERROR_FILE_OPEN); ) printf("enter mode: "); scanf( "%d", &mode); if (mode == 1) ( printf("Entrez le nom de fichier : "); scanf("%1023s", nom de fichier); sortie = fopen(nom de fichier, "w"); if (sortie = = NULL) ( printf("Erreur d'ouverture du fichier %s", nom de fichier); getch(); fclose(origin); exit(ERROR_FILE_OPEN); ) ) else ( output = stdout; ) while (!feof(origin)) ( fprintf (sortie, "%c", fgetc(origine)); ) fclose(origine); fclose(sortie); getch(); )

3. L'utilisateur saisit les données à partir de la console et celles-ci sont écrites dans un fichier jusqu'à ce que la touche Échap soit enfoncée. Consultez le programme et voyez. comment il se comporte si vous entrez en arrière : ce qui est affiché dans le fichier et ce qui est affiché dans la console.

#inclure #inclure #inclure #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 ("Erreur d'ouverture du fichier"); _getch(); exit(ERROR_FILE_OPEN); ) for (;;) ( c = _getch(); if (c == 27) ( break; ) fputc(c, sortie); fputc( c, sortie standard); ) fclose(output); )

4. Le fichier contient des entiers. Trouvez-en le maximum. Profitons du fait que la fonction fscanf renvoie le nombre d'objets correctement lus et correspondants. Le chiffre 1 doit être renvoyé à chaque fois.

#inclure #inclure #inclure #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("Erreur d'ouverture du fichier"); _getch(); exit(ERROR_FILE_OPEN); ) maxn = INT_MIN; hasRead = 1; while (hasRead == 1) ( hasRead = fscanf(input, "%d", &num); if (hasRead != 1) ( continuer; ) if (num >

Une autre solution consiste à lire les nombres jusqu’à la fin du fichier.

#inclure #inclure #inclure #inclure #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("Erreur d'ouverture du fichier"); _getch(); exit(ERROR_FILE_OPEN); ) maxn = INT_MIN; while (!feof(input)) ( fscanf(input, "%d", &num); if (num > maxn ) ( maxn = num; ) ) printf("nombre max = %d", maxn); fclose(input); _getch(); )

5. Le fichier contient des mots : mot russe, tabulation, mot anglais, sur plusieurs lignes. L'utilisateur saisit un mot anglais, il faut sortir le mot russe.

Le fichier de traduction ressemble à ceci

soleil Soleil
stylo à crayon
stylo à bille crayon
porte porte
fenêtre fenêtre
chaise chaise
fauteuil

et enregistré dans l'encodage cp866 (OEM 866). C'est important : la dernière paire de mots se termine également par un saut de ligne.

L'algorithme est le suivant : on lit une ligne d'un fichier, on trouve un caractère de tabulation dans la ligne, on remplace le caractère de tabulation par un zéro, on copie un mot russe du tampon, on copie un mot anglais depuis le tampon, on vérifie l'égalité.

#inclure #inclure #inclure #inclure #define ERROR_FILE_OPEN -3 void main() ( FILE *input = NULL; char buffer; char enWord; char ruWord; char usrWord; index non signé; int length; int wasFound; input = fopen("D:/c/input.txt ", "r"); if (input == NULL) ( printf("Erreur d'ouverture du fichier"); _getch(); exit(ERROR_FILE_OPEN); ) printf("enter word: "); 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. Comptez le nombre de lignes dans le fichier. Nous allons lire le fichier caractère par caractère, en comptant le nombre de caractères "\n" jusqu'à rencontrer le caractère EOF. EOF est un caractère spécial qui indique que la saisie est terminée et qu'il n'y a plus de données à lire. La fonction renvoie une valeur négative en cas d'erreur.
REMARQUE : EOF est de type int, vous devez donc utiliser int pour lire les caractères. De plus, la valeur de EOF n’est pas définie par la norme.

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

Ru-Cyrl 18-tutoriel Sypachev S.S. 1989-04-14 [email protégé] Stépan Sypachevétudiants

Ce n'est toujours pas clair ? – écrire des questions dans la boîte aux lettres

Fichiers texte

Regardons comment travailler avec un fichier texte en C à l'aide d'un exemple. Créez un fichier texte sur le lecteur C nommé TextFile.txt. Tapez les lignes suivantes dans ce fichier :

Chaîne_1 123 Chaîne_11, 456
Chaîne_2
Chaîne_3

Enregistrez le fichier.

Et voici le code d'un programme C qui ouvre notre fichier et en lit les lignes :

/* *Auteur : @author Subbotin B.P..h> #include #define LEN 50 int main(void) ( puts("Opérations sur les fichiers texte"); char cArray; FILE *pTextFile = fopen("C:\\TextFile.txt", "r"); if(pTextFile == NULL) ( puts("Problèmes"); return EXIT_FAILURE; ) while(fgets(cArray, LEN, pTextFile) != NULL) ( printf("%s", cArray); ) fclose(pTextFile); return EXIT_SUCCESS; )

Pour ouvrir un fichier texte en C, utilisez la fonction fopen :

FICHIER *pTextFile = fopen("C:\\TextFile.txt", "r");

Le premier argument de la fonction fopen pointe vers un fichier et le second indique que le fichier est ouvert en lecture.

On lit les lignes à l'aide de la fonction fgets :

fgets(cArray, LEN, pTextFile);

Le premier argument de la fonction fgets pointe vers un tableau de caractères dans lequel seront stockées les chaînes reçues, le deuxième argument est le nombre maximum de caractères à lire et le troisième est notre fichier.

Après avoir fini de travailler avec le fichier, vous devez le fermer :

fclose(pTextFichier);

On a:

Des lettres russes apparaissent également dans les lignes.

Au fait, j'ai créé ce programme dans Eclipse. Vous pouvez voir comment travailler avec C/C++ dans Eclipse.

Nous avons donc ouvert et lu les données d'un fichier texte.

Nous allons maintenant apprendre à créer par programme un fichier texte et à y écrire des données.

/* Auteur : @author Subbotin B.P..h> #include int main(void) ( FILE *pTextFile = fopen("C:\\TextFileW.txt", "w"); char *cString = "Ceci est une chaîne"; char cNewLine = "\n"; int nVal = 123 ; if(pTextFile == NULL) ( puts("Problems"); return EXIT_FAILURE; ) fprintf(pTextFile, "%s%c", cString, cNewLine); fprintf(pTextFile, "%d", nVal); return EXIT_SUCCESS ; )

Créez un fichier texte dans lequel écrire des données :

FICHIER *pTextFile = fopen("C:\\TextFileW.txt", "w");

si le fichier existe déjà, il sera ouvert et toutes les données qu'il contient seront supprimées.

La chaîne C cString et le nombre nVal sont écrits par le programme dans un fichier texte. cNewLine est simplement une nouvelle ligne.

Nous écrivons les données dans un fichier texte à l'aide de la fonction fprintf :

fprintf(pTextFile, "%s%c", cString, cNewLine);

le premier argument ici est notre fichier, le deuxième est la chaîne de format, le troisième ou plus est le nombre d'arguments requis pour ce format.