Comment écrire des informations dans un fichier c. Travailler avec des fichiers en C-Sharp. Classes StreamReader et StreamWriter

Déposer est un ensemble de données stockées sur un périphérique de stockage externe (par exemple, un disque dur). Le fichier a un nom et une extension. L'extension vous permet d'identifier quelles données et dans quel format sont stockées dans le fichier.

Par travailler avec des fichiers, nous entendons :

Création de fichiers ;
- supprimer des fichiers ;
- lire des données ;
- enregistrement des données ;

Modification des paramètres du fichier (nom, extension...) ;
- un autre.

C Sharp a un espace de noms Système.IO, qui implémente toutes les classes dont nous avons besoin pour travailler avec des fichiers. Pour connecter cet espace de noms, vous devez ajouter la ligne using System.IO au tout début du programme. Pour utiliser les encodages, ajoutons également de l'espace en utilisant System.Text ;

utiliser le système ;
en utilisant System.Collections.Generic ;
en utilisant System.Linq ;
en utilisant System.Text ;
en utilisant System.IO ;


Comment créer un fichier ?

Pour créer fichier vide, en classe Déposer il y a une méthode Créer(). Il faut un argument : un chemin. Vous trouverez ci-dessous un exemple de création d'un fichier texte vide new_file.txt sur le lecteur D :

static void Main (arguments de chaîne)
{
Fichier.Create("D:\\new_file.txt");
}


Si un fichier du même nom existe déjà, il sera remplacé par un nouveau fichier vide.

Méthode ÉcrireToutTexte() crée nouveau fichier(s'il n'y en a pas), ou en ouvre un existant et écrit le texte, en remplaçant tout ce qui se trouvait dans le fichier :

static void Main (arguments de chaîne)
{
Déposer. WriteAllText("D:\\new_file.txt", "texte");
}


Méthode AppendAllText() fonctionne comme la méthode WriteAllText() sauf que nouveau texte est ajouté à la fin du fichier, plutôt que d'écraser tout ce qui se trouvait dans le fichier :

static void Main (arguments de chaîne)
{
File.AppendAllText("D:\\new_file.txt", "Texte de la méthode AppendAllText()"); //ajoute du texte à la fin du fichier
}


Comment supprimer un fichier ?

Méthode Supprimer() supprime le fichier au chemin spécifié :

static void Main (arguments de chaîne)
{
Fichier.Delete("d:\\test.txt"); //supprimer le fichier
}


De plus, vous pouvez utiliser des flux pour lire/écrire des données dans un fichier avec C-Sharp.

Couler est une représentation abstraite des données (en octets) qui facilite leur travail. La source de données peut être un fichier, un périphérique d'entrée/sortie ou une imprimante.

Classe Flux est la classe de base abstraite pour toutes les classes de threads en C-Sharp. Pour travailler avec des fichiers, nous avons besoin d'une classe Flux de fichiers (flux de fichiers).

Flux de fichiers- représente un flux qui permet d'effectuer des opérations de lecture/écriture sur un fichier.

static void Main (arguments de chaîne)
{
Fichier FileStream = nouveau FileStream("d:\\test.txt", FileMode.Open
, FileAccess.Read); //ouvre le fichier en lecture seule
}


Modes d'ouverture Mode Fichier:

- Ajouter– ouvre le fichier (s'il existe) et déplace le pointeur vers la fin du fichier (les données seront ajoutées à la fin), ou crée un nouveau fichier. Ce mode possible uniquement avec le mode d'accès FileAccess.Write.
- Créer- crée un nouveau fichier (s'il existe, le remplace)
- CréerNouveau– crée un nouveau fichier (s'il existe, une exception est générée)
- Ouvrir- ouvre le fichier (s'il n'existe pas, une exception est générée)
- OuvrirOuCréer– ouvre un fichier, ou en crée un nouveau s'il n'existe pas
- Tronquer– ouvre un fichier, mais efface toutes les données contenues dans le fichier (si le fichier n'existe pas, une exception est générée)

static void Main (arguments de chaîne)
{
FileStream file1 = new FileStream("d:\\file1.txt", FileMode.CreateNew); //crée un nouveau fichier
FileStream file2 = new FileStream("d:\\file2.txt", FileMode.Open); //ouvre un fichier existant
FileStream file3 = new FileStream("d:\\file3.txt", FileMode.Append); //ouvre le fichier à ajouter à la fin du fichier
}


Mode d'accès Accès aux fichiers:

- Lire– ouvrez le fichier en lecture seule. Une exception est levée lors de la tentative d'écriture
- Écrire- ouvrez le fichier en écriture uniquement. Une exception est levée lors de la tentative de lecture
- LireÉcrire- ouvrir un fichier en lecture et en écriture.

Lecture à partir d'un fichier

Pour lire les données d'un flux, nous avons besoin d'une classe Lecteur de flux. Il implémente de nombreuses méthodes pour faciliter la lecture des données. Vous trouverez ci-dessous un programme qui affiche le contenu d'un fichier à l'écran :

static void Main (arguments de chaîne)
{
FileStream file1 = new FileStream("d:\\test.txt", FileMode.Open); //crée un flux de fichiers
Lecteur StreamReader = nouveau StreamReader(file1); // crée un « lecteur de flux » et l'associe au flux de fichiers
Console.WriteLine(reader.ReadToEnd()); // lit toutes les données du flux et les affiche à l'écran
lecteur.Close(); //ferme le flux
Console.ReadLine();
}


Méthode LireVersFin() lit toutes les données d'un fichier. LireLigne()– lit une ligne (le pointeur du fil se déplace ensuite vers nouvelle ligne, et au prochain appel de la méthode, la ligne suivante sera lue).

Propriété Fin du flux indique si la position actuelle dans le flux est à la fin du flux (la fin du fichier est atteinte). Retours vrai ou FAUX.

Écrire dans un fichier

Pour écrire des données dans un flux, utilisez la classe StreamWriter. Exemple d'écriture dans un fichier :

static void Main (arguments de chaîne)
{
FileStream file1 = new FileStream("d:\\test.txt", FileMode.Create); //crée un flux de fichiers
Writer StreamWriter = new StreamWriter(file1); //crée un « streamwriter » et associe-le à un flux de fichiers
écrivain.Write("texte"); //écrire dans un fichier
écrivain.Close(); //ferme le flux. Sans fermer le flux, rien ne sera écrit dans le fichier
}


Méthode WriteLine()écrit dans le fichier ligne par ligne (comme entrée simple en utilisant Write(), en ajoutant uniquement une nouvelle ligne à la fin).

Vous devez toujours vous rappeler qu'après avoir travaillé avec un flux, vous devez le fermer (libérer des ressources) en utilisant la méthode Fermer().

Codage, dans lequel les données seront lues/écrites, est spécifié lors de la création du StreamReader/StreamWriter :

static void Main (arguments de chaîne)
{
FileStream file1 = new FileStream("d:\\test.txt", FileMode.Open);
Lecteur StreamReader = new StreamReader(file1, Encoding.Unicode);
Writer StreamWriter = new StreamWriter(file1, Encoding.UTF8);
}


De plus, lorsque vous utilisez StreamReader et StreamWriter, vous n'avez pas besoin de créer un flux de fichiers FileStream distinct, mais faites-le immédiatement lors de la création de StreamReader/StreamWriter :

static void Main (arguments de chaîne)
{
StreamWriterwriter = new StreamWriter("d:\\test.txt"); // spécifie le chemin d'accès au fichier, pas le flux
écrivain.WriteLine("texte");
écrivain.Close();
}


Comment créer un dossier ?

En utilisant méthode statique CréerRépertoire() classe Annuaire:

static void Main (arguments de chaîne)
{
Directory.CreateDirectory("d:\\new_folder");
}


Comment supprimer un dossier ?

Pour supprimer des dossiers, utilisez la méthode Supprimer():

static void Main (arguments de chaîne)
{
Directory.Delete("d:\\new_folder"); //supprimer dossier vide
}


Si le dossier n'est pas vide, vous devez spécifier le paramètre de suppression récursive - true :

static void Main (arguments de chaîne)
{
Directory.Delete("d:\\new_folder", true); //supprime le dossier et tout ce qu'il contient
}

Devoirs

Problème 1. Créez un fichier number.txt et écrivez-y des nombres naturels de 1 à 500 séparés par des virgules.

Problème 2. Étant donné un tableau de chaînes : "rouge", "vert", "noir", "blanc", "bleu". Écrivez les éléments du tableau dans le fichier ligne par ligne (chaque élément sur une nouvelle ligne).

Problème 3. Prenez n'importe lequel fichier texte, et trouvez la taille de la ligne la plus longue.

PS. N'oubliez pas de vous abonner aux mises à jour sur e-mail dans le formulaire ci-dessous !

Majorité programmes informatiques travailler avec des fichiers et il est donc nécessaire de créer, supprimer, écrire, lire, ouvrir des fichiers. Qu'est-ce qu'un fichier ? Un fichier est un ensemble nommé d'octets qui peuvent être stockés sur un périphérique de stockage. Eh bien, il est maintenant clair qu'un fichier est compris comme une certaine séquence d'octets, qui a son propre, nom unique, par exemple un fichier .txt. Fichiers avec mêmes noms. Le nom du fichier fait référence non seulement à son nom, mais aussi à son extension, par exemple : fichier.txt et fichier.dat fichiers différents, bien qu'ils aient mêmes noms. Il existe une chose telle que nom et prénom les fichiers sont adresse complète dans le répertoire du fichier en spécifiant le nom du fichier, par exemple : D:\docs\file.txt . Il est important de les comprendre notions de base, sinon il sera difficile de travailler avec des fichiers.

Pour travailler avec des fichiers, vous devez inclure un fichier d'en-tête . DANS plusieurs classes sont définies et les fichiers d'en-tête sont inclus entrée de fichier et sortie de fichier.

Les E/S de fichier sont similaires aux E/S standard, la seule différence est que les E/S sont effectuées vers un fichier plutôt que vers l'écran. Si les E/S sont activées appareils standards est effectué à l'aide des objets cin et cout, puis pour organiser les E/S de fichiers, il suffit de créer vos propres objets qui peuvent être utilisés de la même manière que les opérateurs cin et cout.

Par exemple, vous devez créer un fichier texte et y écrire la ligne Travailler avec des fichiers en C++. Pour ce faire, vous devez suivre les étapes suivantes :

  1. créer un objet classe ofstream ;
  2. associer un objet de classe au fichier dans lequel écrire ;
  3. écrire une ligne dans un fichier ;
  4. fermez le fichier.

Pourquoi faut-il créer un objet de la classe ofstream et non classe ifstream? Parce que vous devez écrire dans un fichier et si vous devez lire des données à partir d'un fichier, un objet de classe ifstream sera créé.

// crée un objet pour écrire dans le fichier ofstream /*nom de l'objet*/; // objet de la classe ofstream

Appelons l'objet fout. Voici ce que nous obtenons :

Ofstream fout;

Pourquoi avons-nous besoin d’un objet ? L'objet doit pouvoir écrire dans un fichier. L'objet a déjà été créé, mais n'est pas associé au fichier dans lequel la chaîne doit être écrite.

Fout.open("cppstudio.txt"); // associe l'objet au fichier

Grâce à l'opération point, nous accédons à la méthode de classe open(), dans laquelle nous indiquons le nom du fichier entre parenthèses. Fichier spécifié sera créé dans le répertoire courant avec le programme. S'il existe un fichier du même nom, alors fichier existant sera remplacé par un nouveau. Ainsi, le fichier est ouvert, il ne reste plus qu'à y écrire la ligne souhaitée. Cela se fait comme ceci :

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

En utilisant l'opération stream en conjonction avec l'objet fout, la chaîne Working with files in C++ est écrite dans un fichier. Puisqu'il n'est plus nécessaire de modifier le contenu du fichier, celui-ci doit être fermé, c'est-à-dire que l'objet doit être séparé du fichier.

Fout.close(); // ferme le fichier

Résultat - un fichier a été créé avec la ligne Working with files in C++.

Les étapes 1 et 2 peuvent être combinées, c'est-à-dire sur une seule ligne, créer un objet et l'associer à un fichier. Cela se fait comme ceci :

Ofstream fout("cppstudio.txt"); // crée un objet de la classe ofstream et l'associe au fichier cppstudio.txt

Combinons tout le code et obtenons le programme suivant.

// file.cpp : Définit le point d'entrée de l'application console. #include "stdafx.h" #include en utilisant l'espace de noms std ; int main(int argc, char* argv) ( ofstream fout("cppstudio.txt"); // crée un objet de la classe ofstream pour l'enregistrement et l'associe au fichier cppstudio.txt fout<< "Работа с файлами в С++"; // запись строки в файл fout.close(); // закрываем файл system("pause"); return 0; }

Reste à vérifier que le programme fonctionne correctement, et pour cela, ouvrez le fichier cppstudio.txt et regardez son contenu, ça devrait être - Travailler avec des fichiers en C++.

  1. créer un objet de la classe ifstream et l'associer au fichier à partir duquel la lecture sera effectuée ;
  2. lire le fichier ;
  3. fermez le fichier.
#inclure en utilisant l'espace de noms std ; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // affichage correct du caractère cyrillique buff; // tampon de stockage intermédiaire du texte lu dans un fichier ifstream fin("cppstudio.txt") ; // fichier ouvert pour lire fin >><< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку system("pause"); return 0; }

Le programme montre deux façons de lire à partir d'un fichier, la première utilise l'opération de transfert vers un flux, la seconde utilise la fonction obtenir la ligne() . Dans le premier cas, seul le premier mot est lu, et dans le second cas, une chaîne de 50 caractères est lue. Mais comme il reste moins de 50 caractères dans le fichier, les caractères jusqu'au dernier inclus sont lus. Veuillez noter que lire une deuxième fois (ligne 17) a continué après le premier mot, et non depuis le début, puisque le premier mot a été lu dansligne 14. Le résultat du programme est présenté dans la figure 1.

Travailler avec des fichiers en C++ Pour continuer, appuyez sur n'importe quelle touche. . .

Figure 1 - Utilisation de fichiers en C++

Le programme a fonctionné correctement, mais cela n'arrive pas toujours, même si tout est en ordre avec le code. Par exemple, le nom d'un fichier inexistant a été transmis au programme ou il y a eu une erreur dans le nom. Et alors ? Dans ce cas, il ne se passera rien du tout. Le fichier ne sera pas trouvé, ce qui signifie qu'il ne sera pas possible de le lire. Par conséquent, le compilateur ignorera les lignes où le travail est effectué sur le fichier. En conséquence, le programme se fermera correctement, mais rien ne s'affichera à l'écran. Il semblerait que ce soit une réaction tout à fait normale face à une telle situation. Mais un simple utilisateur ne comprendra pas ce qui se passe et pourquoi la ligne du fichier n'apparaît pas à l'écran. Donc, pour que tout soit très clair, C++ fournit une telle fonction - is_open(), qui renvoie des valeurs entières : 1 - si le fichier a été ouvert avec succès, 0 - si le fichier n'a pas été ouvert. Modifions le programme en ouvrant un fichier, de sorte que si le fichier n'est pas ouvert, un message correspondant s'affiche.

// file_read.cpp : Définit le point d'entrée de l'application console. #include "stdafx.h" #include #inclure en utilisant l'espace de noms std ; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // affichage correct du caractère cyrillique buff; // tampon de stockage intermédiaire du texte lu dans un fichier ifstream fin("cppstudio.doc") ; // ( VOUS ENTREZ UN NOM DE FICHIER INVALIDE) if (!fin.is_open()) // si le fichier n'est pas ouvert cout<< "Файл не может быть открыт!\n"; // сообщить об этом else { fin >> chamois ; // compte le premier mot du fichier cout<< buff << endl; // напечатали это слово fin.getline(buff, 50); // считали строку из файла fin.close(); // закрываем файл cout << buff << endl; // напечатали эту строку } system("pause"); return 0; }

Le résultat du programme est présenté dans la figure 2.

Le fichier ne peut pas être ouvert ! Pour continuer, appuyez sur n’importe quelle touche. . .

Figure 2 - Travailler avec des fichiers en C++

Comme le montre la figure 2, le programme a signalé qu'il était impossible d'ouvrir le fichier. Par conséquent, si le programme fonctionne avec des fichiers, il est recommandé d'utiliser cette fonction, is_open(), même si vous êtes sûr que le fichier existe.

Modes d'ouverture de fichiers

Les modes d'ouverture de fichiers déterminent la manière dont les fichiers sont utilisés. Pour définir le mode, la classe ios_base fournit des constantes qui déterminent le mode d'ouverture du fichier (voir Tableau 1).

Les modes d'ouverture de fichiers peuvent être définis directement lors de la création d'un objet ou lors de l'appel de la fonction open() .

Ofstream fout("cppstudio.txt", ios_base::app); // ouvre le fichier pour ajouter des informations à la fin du fichier fout.open("cppstudio.txt", ios_base::app); // ouvre le fichier pour ajouter des informations à la fin du fichier

Les modes d'ouverture de fichiers peuvent être combinés à l'aide d'une opération logique au niveau du bit ou| , par exemple : ios_base::out | ios_base::trunc - ouvre un fichier en écriture après l'avoir effacé.

Les objets de la classe ofstream, lorsqu'ils sont associés à des fichiers, contiennent par défaut des modes d'ouverture de fichiers ios_base::out | ios_base ::trunc . Autrement dit, le fichier sera créé s'il n'existe pas. Si le fichier existe, son contenu sera supprimé et le fichier lui-même sera prêt à être écrit. Les objets de la classe ifstream lorsqu'ils sont associés à un fichier ont le mode d'ouverture de fichier par défaut ios_base::in - le fichier est ouvert en lecture seule. Le mode d'ouverture du fichier est également appelé drapeau ; pour des raisons de lisibilité, nous utiliserons ce terme à l'avenir. Le tableau 1 ne répertorie pas tous les indicateurs, mais ceux-ci devraient suffire pour vous aider à démarrer.

Notez que les indicateurs ate et app ont une description très similaire, ils déplacent tous deux le pointeur vers la fin du fichier, mais l'indicateur app permet uniquement d'écrire jusqu'à la fin du fichier, et l'indicateur ate déplace simplement le drapeau vers la fin. du fichier et ne limite pas où écrire.

Développons un programme qui, à l'aide de l'opération sizeof(), calculera les caractéristiques des principaux types de données en C++ et les écrira dans un fichier. Caractéristiques:

  1. nombre d'octets alloués au type de données
  2. la valeur maximale qu'un type de données particulier peut stocker.

Le fichier doit être écrit au format suivant :

/* type de données octet valeur maximale bool = 1 255,00 char = 1 255,00 short int = 2 32767,00 unsigned short int = 2 65535,00 int = 4 2147483647,00 unsigned int = 4 4294967295,00 long int = 4 ,00 non signé long int = 4 4294967295.00 flotteur = 4 2147483647.00 flotteur long = 8 9223372036854775800.00 double = 8 9223372036854775800.00 */

Un tel programme a déjà été développé plus tôt dans la section, mais là, toutes les informations sur les types de données ont été sorties sur le périphérique de sortie standard, et nous devons refaire le programme pour que les informations soient écrites dans un fichier. Pour ce faire, vous devez ouvrir le fichier en mode écriture, avec troncature préalable des informations du fichier actuel ( ligne 14). Une fois le fichier créé et ouvert avec succès (lignes 16 à 20), au lieu de l'instruction cout, dans ligne 22 nous utilisons l'objet fout. ainsi, au lieu de l'écran, les informations sur le type de données seront écrites dans un fichier.

// write_file.cpp : Définit le point d'entrée de l'application console. #include "stdafx.h" #include #inclure // travailler avec des fichiers #include // manipulateurs d'entrée/sortie utilisant l'espace de noms std ; int main(int argc, char* argv) ( setlocale(LC_ALL, "rus"); // associe l'objet au fichier et ouvre le fichier en mode écriture, en supprimant d'abord toutes les données ofstream fout("data_types.txt ", ios_base::out | ios_base::trunc); if (!fout.is_open()) // si le fichier n'a pas été ouvert ( cout<< "Файл не может быть открыт или создан\n"; // напечатать соответствующее сообщение return 1; // выполнить выход из программы } fout << " data type " << "byte" << " " << " max value "<< endl // en-têtes de colonnes <<"bool = " << sizeof(bool) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных bool*/ << (pow(2,sizeof(bool) * 8.0) - 1) << endl << "char = " << sizeof(char) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных char*/ << (pow(2,sizeof(char) * 8.0) - 1) << endl << "short int = " << sizeof(short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных short int*/ << (pow(2,sizeof(short int) * 8.0 - 1) - 1) << endl << "unsigned short int = " << sizeof(unsigned short int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned short int*/ << (pow(2,sizeof(unsigned short int) * 8.0) - 1) << endl << "int = " << sizeof(int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных int*/ << (pow(2,sizeof(int) * 8.0 - 1) - 1) << endl << "unsigned int = " << sizeof(unsigned int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных unsigned int*/ << (pow(2,sizeof(unsigned int) * 8.0) - 1) << endl << "long int = " << sizeof(long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long int*/ << (pow(2,sizeof(long int) * 8.0 - 1) - 1) << endl << "unsigned long int = " << sizeof(unsigned long int) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных undigned long int*/ << (pow(2,sizeof(unsigned long int) * 8.0) - 1) << endl << "float = " << sizeof(float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных float*/ << (pow(2,sizeof(float) * 8.0 - 1) - 1) << endl << "long float = " << sizeof(long float) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных long float*/ << (pow(2,sizeof(long float) * 8.0 - 1) - 1) << endl << "double = " << sizeof(double) << " " << fixed << setprecision(2) /*вычисляем максимальное значение для типа данных double*/ << (pow(2,sizeof(double) * 8.0 - 1) - 1) << endl; fout.close(); // программа больше не использует файл, поэтому его нужно закрыть cout << "Данные успешно записаны в файл data_types.txt\n"; system("pause"); return 0; }

Il est impossible de ne pas remarquer que les changements dans le programme sont minimes, et tout cela grâce au fait que les entrées/sorties standard et les entrées/sorties de fichiers sont utilisées exactement de la même manière. A la fin du programme, àligne 45Nous avons explicitement fermé le fichier, bien que cela ne soit pas nécessaire, mais que cela soit considéré comme une bonne pratique de programmation. Il convient de noter que toutes les fonctions et manipulateurs utilisés pour formater les entrées/sorties standard sont également pertinents pour les entrées/sorties de fichiers. Par conséquent, aucune erreur ne s'est produite lorsque l'instruction cout a été remplacé par un objet fout.

Caractéristiques du langage C. Guide d'étude.

Ouverture et fermeture de fichiers

Auparavant, lors de la saisie et de la sortie de données, nous travaillions avec des flux standard - le clavier et le moniteur. Voyons maintenant comment le langage C implémente la réception de données à partir de fichiers et leur écriture là-bas. Avant de pouvoir effectuer ces opérations, vous devez ouvrir le fichier et y accéder.

Dans le langage de programmation C, un pointeur vers un fichier est de type FILE et sa déclaration ressemble à ceci :
DÉPOSER *monfichier ;

Par contre, la fonction fopen () ouvre un fichier à l'adresse spécifiée comme premier argument en mode lecture ("r"), mode écriture ("w") ou mode ajout ("a") et renvoie un pointeur vers celui-ci au programme. Par conséquent, le processus d'ouverture d'un fichier et de connexion au programme ressemble à ceci :
monfichier = fopen("bonjour.txt" , "r" ) ;

Lors de la lecture ou de l'écriture de données dans un fichier, on y accède via un pointeur de fichier (dans ce cas, myfile ).

Si pour une raison ou une autre (il n'y a pas de fichier à l'adresse indiquée, l'accès à celui-ci est refusé) la fonction fopen () ne peut pas ouvrir le fichier, alors il renvoie NULL. Dans les programmes réels, ils gèrent presque toujours une erreur lors de l'ouverture d'un fichier dans une branche si, nous l'omettrons davantage.

Déclarer la fonction fopen () est contenu dans le fichier d'en-tête stdio.h, il doit donc être inclus. Également dans stdio.h, le type de structure FILE est déclaré.

Une fois le travail terminé avec un fichier, il est d'usage de le fermer pour libérer le tampon des données et pour d'autres raisons. Ceci est particulièrement important si le programme continue de s'exécuter après avoir travaillé avec le fichier. La rupture de la connexion entre un fichier externe et un pointeur vers celui-ci depuis le programme se fait à l'aide de la fonction fclose () . Un pointeur vers le fichier lui est passé en paramètre :
ffermer (monfichier) ;

Plus d'un fichier peut être ouvert dans le programme. Dans ce cas, chaque fichier doit être associé à son propre pointeur de fichier. Cependant, si le programme travaille d'abord avec un fichier puis le ferme, le pointeur peut être utilisé pour ouvrir un deuxième fichier.

Lire et écrire dans un fichier texte

fscanf()

fonction fscanf () similaire dans sa signification à la fonction scanf () , mais contrairement à lui, il fournit une entrée formatée à partir d'un fichier, plutôt que le flux d'entrée standard. fonction fscanf () accepte des paramètres : pointeur de fichier, chaîne de format, adresses des zones mémoire pour l'écriture des données :
fscanf (monfichier, "%s%d" , str, & a) ;

Renvoie le nombre de données lues avec succès ou EOF. Les espaces et les caractères de nouvelle ligne sont comptés comme délimiteurs de données.

Disons que nous avons un fichier contenant la description suivante des objets :

Pommes 10 23,4 bananes 5 25,0 pain 1 10,3

#inclure main () ( FILE * fichier; struct food ( char name[ 20] ; quantité non signée; 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", boutique[ i].nom , boutique[ i].qté , boutique[ i].prix ) ;

je++; () ) )

Dans ce cas, une structure et un tableau de structures sont déclarés. Chaque ligne du fichier correspond à un élément du tableau ; un élément de tableau est une structure contenant une chaîne et deux champs numériques. La boucle lit une ligne par itération. Lorsque la fin du fichier fscanf est rencontrée

renvoie EOF et la boucle se termine. () fgets() () fonction fgets () similaire à la fonction gets () et effectue une saisie ligne par ligne à partir du fichier. Un appel à fgets
vous permettra de lire une ligne. Dans ce cas, vous ne pouvez pas lire la ligne entière, mais seulement une partie depuis le début. fget les paramètres ( ressemble à ça : )

fgets
vous permettra de lire une ligne. Dans ce cas, vous ne pouvez pas lire la ligne entière, mais seulement une partie depuis le début. fget les paramètres array_of_characters, number_of_characters_read, pointer_to_file

Par exemple: () (str, 50 , monfichier)

#inclure Cet appel de fonction lira dans le fichier associé au pointeur monfichier une ligne complète de texte si sa longueur est inférieure à 50 caractères, y compris le caractère "\n", que la fonction stockera également dans un tableau. Le dernier (50ème) élément du tableau str sera le caractère "\0" ajouté par fgets \n". Si la chaîne est plus longue, la fonction lira 49 caractères et écrira "\0" à la fin. Dans ce cas, "\n" ne sera pas contenu dans la ligne de lecture.

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

fclose(fichier) ;

) () Dans ce programme, contrairement au précédent, les données sont lues ligne par ligne dans le tableau arr. A la lecture de la ligne suivante, la précédente est perdue. fonction fgets () renvoie NULL s'il ne peut pas lire la ligne suivante.

getc() ou fgetc() \n" fonction getc \0 " ou fgetc \n"(les deux fonctionnent) vous permet d'obtenir le caractère suivant du fichier. \0 " ou fgetc \n" while ((arr[ i] = fgetc (file) ) != EOF) ( if (arr[ i] == "

) (arr[je] = "

;

printf("%s

  • , arr) ; ( je = 0 ; ) .
  • Sortie post-par-ligne. fonction fputs ( chaîne, pointeur_fichier ) .
  • Sortie caractère par caractère. fonction fputc () ou putc ( symbole, pointeur_fichier ) .

Vous trouverez ci-dessous des exemples de code qui utilisent trois méthodes de sortie de données dans un fichier.

Écriture des champs d'une structure sur chaque ligne du fichier :

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

, boutique[ i].nom , boutique[ i].qté , boutique[ i].prix ) ; () je++; () )

Sortie ligne par ligne dans un fichier ( fputs \n", contrairement aux put

lui-même ne place pas "\n" à la fin de la ligne) :

while (obtient (arr) != NULL) ( fputs(arr, fichier) ; fputs("

, déposer); )

Exemple de sortie caractère par caractère :

while ((i = getchar() ) != EOF) putc(i, file) ; () Lire et écrire dans un fichier binaire

Vous pouvez travailler avec un fichier non pas comme une séquence de caractères, mais comme une séquence d'octets. En principe, il n'est pas possible de travailler autrement avec des fichiers non texte. Cependant, vous pouvez lire et écrire dans des fichiers texte de cette façon. L'avantage de cette méthode d'accès à un fichier est la vitesse de lecture-écriture : un bloc d'information important peut être lu/écrit en un seul accès.

Lors de l'ouverture d'un fichier pour un accès binaire, le deuxième paramètre de la fonction fopen () est la chaîne "rb" ou "wb". () Le sujet du travail avec des fichiers binaires est assez complexe et nécessite une leçon distincte pour l'étudier. Ici, seules les caractéristiques des fonctions de lecture et d'écriture dans un fichier, considéré comme un flux d'octets, seront notées.

  1. fonctions d'effroi
  2. et écrire
  3. prendre comme paramètres :
  4. adresse de la zone mémoire où les données sont écrites ou lues,

la taille d'un type donné,

la quantité de données lues de la taille spécifiée, () est la chaîne "rb" ou "wb". () :

#inclure index des fichiers. Ces fonctions renvoient le nombre de données lues ou écrites avec succès. Ceux. vous pouvez « commander » la lecture de 50 données, mais n’en recevoir que 10. Il n’y aura pas d’erreur. \0 " Exemple d'utilisation des fonctions fread \n"#inclure \0 " main () ( FILE * fichier; char Shelf1[ 50] , Shelf2[ 100] ; int n, m; file = fopen("shelf1.txt" , "rb" ) ; n= fread(shelf1, sizeof (char ) , 50, fichier) ; fclose(file) ; file = fopen("shelf2.txt" , "rb" ) ; m= fread(shelf2, sizeof (char ) , 50, fichier) = "

Ici, une tentative est faite pour lire 50 caractères du premier fichier. n stocke le nombre de caractères réellement lus. La valeur de n peut être inférieure ou égale à 50. Les données sont placées dans une ligne. La même chose se produit avec le deuxième fichier. Ensuite, la première ligne est ajoutée à la seconde et les données sont transférées dans le troisième fichier.

Résolution de problèmes

Exercice

  1. Écrivez un programme qui demande à l'utilisateur le nom (adresse) d'un fichier texte, puis l'ouvre et compte le nombre de caractères et de lignes qu'il contient.
  2. Écrivez un programme qui écrit dans un fichier les données reçues d'un autre fichier et modifiées d'une manière ou d'une autre avant l'écriture. Chaque ligne de données obtenue à partir d'un fichier doit s'inscrire dans une structure.

Classe Flux de fichiers représente les capacités de lecture à partir d'un fichier et d'écriture dans un fichier. Il vous permet de travailler à la fois avec des fichiers texte et des fichiers binaires.

Considérons ses propriétés et méthodes les plus importantes :

    Propriété Longueur : renvoie la longueur du flux en octets

    Propriété Position : renvoie la position actuelle dans le flux

    Méthode Read : lit les données d’un fichier dans un tableau d’octets. Prend trois paramètres : int Read (tableau d'octets, int offset, int count) et renvoie le nombre d'octets lus avec succès. Les paramètres suivants sont utilisés ici :

    • array - un tableau d'octets où les données lues dans le fichier seront placées

      offset représente le décalage en octets dans le tableau dans lequel les octets lus seront placés

      count - le nombre maximum d'octets à lire. S'il y a moins d'octets dans le fichier, ils seront tous lus.

    Méthode recherche longue (décalage long, origine SeekOrigin): définit la position dans le flux avec un décalage du nombre d'octets spécifié dans le paramètre offset.

    Méthode d'écriture : écrit les données d'un tableau d'octets dans un fichier. Prend trois paramètres : Write (tableau d'octets, décalage int, nombre int)

    • array - un tableau d'octets à partir duquel les données seront écrites dans le fichier

      offset - le décalage en octets dans le tableau à partir duquel les octets commencent à être écrits dans le flux

      count - nombre maximum d'octets à écrire

FileStream représente l'accès aux fichiers au niveau des octets. Ainsi, par exemple, si vous devez lire ou écrire une ou plusieurs lignes dans un fichier texte, le tableau d'octets doit être converti en chaînes à l'aide de méthodes spéciales. Par conséquent, d'autres classes sont utilisées pour travailler avec des fichiers texte.

En même temps, lorsque vous travaillez avec divers fichiers binaires ayant une certaine structure, FileStream peut être très utile pour extraire certaines informations et les traiter.

Regardons un exemple de lecture et d'écriture dans un fichier texte :

Console.WriteLine("Entrez une ligne pour écrire dans le fichier :"); texte de chaîne = Console.ReadLine(); // écriture dans un fichier en utilisant (FileStream fstream = new FileStream (@"C:\SomeDir\noname\note.txt", FileMode.OpenOrCreate)) ( // convertit la chaîne en octets tableau d'octets = System.Text.Encoding. Par défaut. GetBytes(text); // écriture d'un tableau d'octets dans un fichier fstream.Write(array, 0, array.Length); Console.WriteLine("Texte écrit dans un fichier"); fstream = File. OpenRead (@"C:\SomeDir\noname\note.txt")) ( // convertit la chaîne en octets byte array = new byte; // lit les données fstream.Read (array, 0, array. Longueur); // décode les octets en chaîne textFromFile = System.Text.Encoding.Default.GetString(array); Console.WriteLine("Texte du fichier : (0)", textFromFile ) Console.ReadLine();

Regardons cet exemple. La lecture et l'écriture utilisent l'instruction using. Cette instruction ne doit pas être confondue avec la directive using, qui inclut des espaces de noms au début du fichier de code. L'instruction using vous permet de créer un objet dans un bloc de code, à la fin duquel la méthode Dispose de cet objet est appelée, et ainsi l'objet est détruit. Dans ce cas, la variable fstream sert d'objet.

L'objet fstream est créé de deux manières différentes : via le constructeur et via l'une des méthodes statiques de la classe File.

Ici, deux paramètres sont transmis au constructeur : le chemin du fichier et l'énumération FileMode. Cette énumération indique le mode d'accès au fichier et peut prendre les valeurs suivantes :

    Ajouter : si le fichier existe, le texte est ajouté à la fin du fichier. Si le fichier n'existe pas, il est créé. Le fichier est ouvert en écriture uniquement.

    Créer : Un nouveau fichier est créé. Si un tel fichier existe déjà, il est écrasé

    CreateNew : un nouveau fichier est créé. Si un tel fichier existe déjà, l'application renvoie une erreur

    Ouvrir : ouvre un fichier. Si le fichier n'existe pas, une exception est levée

    OpenOrCreate : si le fichier existe, il est ouvert, sinon, un nouveau est créé

    Tronquer : si le fichier existe, il est écrasé. Le fichier est ouvert en écriture uniquement.

La méthode statique OpenRead de la classe File ouvre un fichier en lecture et renvoie un objet FileStream.

Le constructeur de classe FileStream dispose également d'un certain nombre de surcharges qui vous permettent de personnaliser plus précisément l'objet en cours de création. Toutes ces versions peuvent être consultées sur msdn.

L'écriture et la lecture utilisent l'objet d'encodage Encoding.Default de l'espace de noms System.Text. Dans ce cas, nous utilisons deux de ses méthodes : GetBytes pour obtenir un tableau d'octets à partir d'une chaîne et GetString pour obtenir une chaîne à partir d'un tableau d'octets.

En conséquence, la chaîne que nous avons saisie est écrite dans le fichier note.txt. Essentiellement, il s'agit d'un fichier binaire (pas d'un fichier texte), bien que si nous y écrivons seulement une ligne, nous pouvons visualiser ce fichier sous une forme lisible par l'homme en l'ouvrant dans un éditeur de texte. Cependant, si nous y écrivons des octets aléatoires, par exemple :

Fstream.WriteByte(13); fstream.WriteByte(103);

Nous pourrions alors avoir des difficultés à le comprendre. Par conséquent, des classes distinctes sont conçues pour fonctionner directement avec des fichiers texte : StreamReader et StreamWriter.

Accès aléatoire aux fichiers

Souvent, les fichiers binaires représentent une structure spécifique. Et, connaissant cette structure, nous pouvons extraire l'information nécessaire du fichier ou, à l'inverse, écrire un certain ensemble d'octets à un certain endroit du fichier. Par exemple, dans les fichiers wav, les données audio elles-mêmes commencent à 44 octets, et jusqu'à 44 octets contiennent diverses métadonnées - le nombre de canaux audio, la fréquence d'échantillonnage, etc.

En utilisant la méthode Seek(), nous pouvons contrôler la position du curseur de flux, à partir de laquelle le fichier est lu ou écrit. Cette méthode prend deux paramètres : le décalage et la position dans le fichier. Une position dans un fichier est décrite par trois valeurs :

    SeekOrigin.Begin : début du fichier

    SeekOrigin.End : fin du fichier

    SeekOrigin.Current : position actuelle dans le fichier

Le curseur du flux à partir duquel commence la lecture ou l'écriture est décalé vers l'avant d'un décalage par rapport à la position spécifiée comme deuxième paramètre. Le décalage peut être négatif, puis le curseur se déplace vers l'arrière, s'il est positif, puis vers l'avant.

Regardons un exemple :

Utilisation de System.IO ; en utilisant System.Text ; programme de classe ( static void Main(string args) ( string text = "hello world"; // écriture dans un fichier en utilisant (FileStream fstream = new FileStream (@"D:\note.dat", FileMode.OpenOrCreate)) ( / / convertir la chaîne en octets input = Encoding.Default.GetBytes(text); // écrire un tableau d'octets dans un fichier fstream.Write(input, 0, input.Length); ); déplacez le pointeur vers la fin du fichier, cinq octets à la fin du fichier fstream.Seek(-5, SeekOrigin.End); // moins 5 caractères à partir de la fin du flux // lit quatre caractères à partir du position actuelle byte output = new byte( output, 0, output.Length); // décode les octets en une chaîne string textFromFile = Encoding.Default.GetString(output); Console.WriteLine("Texte du fichier : (0)" , textFromFile); dans le fichier le mot monde à la chaîne de mots maison replaceText = "house"; fstream.Seek(-5, SeekOrigin.End); // moins 5 caractères à partir de la fin du flux input = Encoding.Default. GetBytes(replaceText); , 0, input.Length);

// lit le fichier en entier // renvoie le pointeur vers le début du fichier fstream.Seek(0, SeekOrigin.Begin);

sortie = nouvel octet ;

fstream.Read(sortie, 0, sortie.Longueur);

// décode les octets en une chaîne textFromFile = Encoding.Default.GetString(output);

Console.WriteLine("Texte du fichier : (0)", textFromFile); // bonjour la maison ) Console.Read();

) )

Sortie de la console :

Texte écrit dans le fichier Texte du fichier : worl Texte du fichier : hello house

FileStream fstream = nul ; try ( fstream = new FileStream (@"D:\note3.dat", FileMode.OpenOrCreate); // opérations avec le flux ) catch(Exception ex) ( ) enfin ( if (fstream != null) fstream.Close() ; )

Si nous n'utilisons pas la construction using, alors nous devons appeler explicitement la méthode Close() : fstream.Close()

J'avoue : « Je n'ai aucune idée de comment écrire une structure dans un fichier s'il y a des pointeurs à l'intérieur de ses champs. » Je peux enregistrer chaque champ individuellement, mais ce n'est pas ce que j'aimerais vraiment. En fait, j’aimerais écrire toute la structure d’un coup, et une telle possibilité existe pour les structures. (Le seul bémol est que my: « existe » fait référence à des structures sans pointeurs. Je ne sais pas avec des pointeurs (je pense que pour les structures avec des pointeurs, il suffit de traiter les champs individuellement).

Ainsi, pour écrire une structure dans un fichier, il est nécessaire qu’il existe une telle structure que nous souhaitons écrire. Logique? – logique. On commence donc par écrire une structure simple

PHP

struct mystruct //Structure MyStruct à trois champs (i,buf,d) ( long i; char buf; double d; ); int main() ( mystruct X; //Déclare une structure X dont le type est mystruct return 0; )

C'est probablement assez simple et compréhensible. Nous avons créé une structure et une variable du type de la structure créée. Reste maintenant la partie la plus importante : écrire la structure dans un fichier. Pour écrire une structure dans un fichier, vous devez connaître la taille de la structure.
Parlons à nouveau des pointeurs. S’il y a des pointeurs dans les champs de la structure, alors la taille correcte de la structure ne sera pas connue. La taille d'un objet ne peut pas être extraite du pointeur. Il est possible de connaître la taille du pointeur lui-même, mais pas la taille de l'objet vers lequel il pointe. Cela pose des difficultés notables. Un pointeur reste un pointeur, une connerie complexe.
Revenons à l'écriture d'une structure simple dans un fichier. Pour écrire une structure dans un fichier, vous devez indiquer au compilateur l'adresse de la structure, un pointeur de transtypage vers char et la taille de la structure à écrire. C'est fait comme ça

PHP

#inclure #inclure #inclure struct mystruct ( long i; char buf; double d; ); int main() ( const char *FName="d:\\txt"; //Chemin d'accès au fichier. Entrez le vôtre. mystruct X; //memset(&ms,0,sizeof ms); //vous pouvez initialiser le structurer les éléments avec des zéros comme ceci X.i = 10; //écrire la valeur dans le champ i X.d = 2; //écrire la valeur dans le champ d strcpy(X.buf,"site"); buf field //ouvre le fichier d'écriture du flux f(FName) ,ios::binary|ios::out); f.write((char*)&X,sizeof X); //Écrit la structure entière f.close(); ); strcpy(X.buf,"\0"); //Je change le champ buf de la structure X X.i=0; //Je change le champ i de la structure X //ouvre le fichier de lecture ifstream dans(FName, ios::binary|ios::in); &X,sizeof X //Lire la structure entière en même temps in.close();<

#inclure

#inclure

#inclure

struct mastruct (

longtemps je ;

char buf[255];

double d ;

} ;

int principal()

const char * FName = "d:\\txt" ; //Chemin d'accès au fichier. Entrez le vôtre.

mastruct X ;

//memset(&ms,0,taillede ms); //vous pouvez initialiser les éléments de structure avec des zéros comme ceci

X. je = 10 ; //écrit la valeur dans le champ i

X. d = 2 ; //écrit la valeur dans le champ d

dans. fermer();

cout<< X . buf << "\n" ; //Sort la valeur du champ de structure. C'est égal au site

renvoie 0 ;

Je ne peux pas très bien expliquer la ligne avec l’entrée dans le fichier. Cette syntaxe est plus facile à retenir, l'essentiel est que le premier paramètre utilise un pointeur vers char, c'est pourquoi le transtypage vers un tel pointeur est utilisé, et après la virgule vient le deuxième paramètre. Le deuxième paramètre spécifie la taille à utiliser pour écrire dans le fichier. Ceux qui sont familiers avec le casting de caractères devraient comprendre ce qui se passe ; ceux qui ne le connaissent pas devraient s'y habituer. La compréhension viendra.

  • (char*)&X -> Notation peu pratique. Il faut le lire de droite à gauche. Adresse du bâtiment X Un pointeur vers char est converti en type. Ceci est nécessaire pour indiquer la méthode écrire (lire) l'adresse de la structure sous la forme dont elle a besoin. Lisez attentivement de droite à gauche, la seule chose : &X = adresse de la structure X, et gardez à l’esprit que ce type de relecture est souvent pratique lorsque vous travaillez avec des pointeurs.

Voici un exemple d'écriture d'une structure dans un fichier et de lecture des données du fichier dans la structure pour les débutants. Cet exemple est relativement simple. La principale chose à comprendre est que lorsque vous ouvrez un fichier pour traitement, vous devez le fermer après traitement. Lorsque vous lisez ou écrivez une structure à partir d'un fichier à l'aide de l'algorithme décrit, vous devez convertir l'adresse de la structure en un pointeur vers le type char et signaler la taille de la structure. Il ne faut pas oublier que les pointeurs : « Merde complexe » et leur utilisation peuvent soit être trompeurs, soit vous obliger à écrire du code plus complexe. Je souhaite également attirer une fois de plus votre attention sur le fait que vous ne pouvez pas attribuer une chaîne à un tableau de caractères et que pour y écrire une valeur, vous devez utiliser des techniques de copie.

L'article a été entièrement réécrit le 7 janvier 2014.

    Si vous voyez des articles similaires, mais avec des pointeurs, sachez qu'ils sont faux et que je dois les corriger. Merci de les signaler. Je ne peux pas tout suivre moi-même, mais je ne veux pas non plus induire en erreur



Des questions ?

Signaler une faute de frappe

Texte qui sera envoyé à nos rédacteurs :