Gestion de fichiers en C - Comment ouvrir, fermer et écrire dans des fichiers

Si vous avez déjà écrit le helloworldprogramme C , vous connaissez déjà les E / S de fichier de base en C:

/* A simple hello world in C. */ #include  // Import IO functions. #include  int main() { // This printf is where all the file IO magic happens! // How exciting! printf("Hello, world!\n"); return EXIT_SUCCESS; }

La gestion des fichiers est l'une des parties les plus importantes de la programmation. En C, nous utilisons un pointeur de structure d'un type de fichier pour déclarer un fichier:

FILE *fp;

C fournit un certain nombre de fonctions intégrées pour effectuer des opérations de base sur les fichiers:

  • fopen() - créer un nouveau fichier ou ouvrir un fichier existant
  • fclose() - fermer un fichier
  • getc() - lit un caractère dans un fichier
  • putc() - écrit un caractère dans un fichier
  • fscanf() - lit un ensemble de données à partir d'un fichier
  • fprintf() - écrit un ensemble de données dans un fichier
  • getw() - lit un entier dans un fichier
  • putw() - écrit un entier dans un fichier
  • fseek() - définir la position au point souhaité
  • ftell() - donne la position actuelle dans le fichier
  • rewind() - régler la position au point de départ

Ouvrir un fichier

La fopen()fonction permet de créer un fichier ou d'ouvrir un fichier existant:

fp = fopen(const char filename,const char mode);

Il existe de nombreux modes pour ouvrir un fichier:

  • r - ouvrir un fichier en lecture
  • w - ouvre ou crée un fichier texte en mode écriture
  • a - ouvre un fichier en mode ajout
  • r+ - ouvre un fichier en mode lecture et écriture
  • a+ - ouvre un fichier en mode lecture et écriture
  • w+ - ouvre un fichier en mode lecture et écriture

Voici un exemple de lecture de données à partir d'un fichier et d'écriture dessus:

#include #include main() { FILE *fp; char ch; fp = fopen("hello.txt", "w"); printf("Enter data"); while( (ch = getchar()) != EOF) { putc(ch,fp); } fclose(fp); fp = fopen("hello.txt", "r"); while( (ch = getc(fp)! = EOF) printf("%c",ch); fclose(fp); }

Maintenant, vous pensez peut-être: "Ceci imprime simplement le texte à l'écran. Comment est ce fichier IO?"

La réponse n'est pas évidente au début et nécessite une certaine compréhension du système UNIX. Dans un système UNIX, tout est traité comme un fichier, ce qui signifie que vous pouvez y lire et y écrire.

Cela signifie que votre imprimante peut être abstraite sous forme de fichier puisque tout ce que vous faites avec une imprimante est d'écrire avec elle. Il est également utile de considérer ces fichiers comme des flux, car comme vous le verrez plus tard, vous pouvez les rediriger avec le shell.

Alors, comment cela se rapporte-t-il aux helloworldE / S?

Lorsque vous appelez printf, vous écrivez simplement dans un fichier spécial appelé stdout, abréviation de sortie standard . stdoutreprésente la sortie standard telle que décidée par votre shell, qui est généralement le terminal. Cela explique pourquoi il s'est imprimé sur votre écran.

Il existe deux autres flux (c'est-à-dire des fichiers) qui vous sont accessibles avec effort, stdinet stderr. stdinreprésente l' entrée standard , que votre shell attache généralement au clavier. stderrreprésente la sortie d' erreur standard , que votre shell attache généralement au terminal.

Fichier IO rudimentaire ou comment j'ai appris à poser des tuyaux

Assez de théorie, passons aux choses sérieuses en écrivant du code! La meilleure façon d'écrire dans un fichier est de rediriger le flux de sortie en utilisant la sortie outil redirect, >.

Si vous souhaitez ajouter, vous pouvez utiliser >>:

# This will output to the screen... ./helloworld # ...but this will write to a file! ./helloworld > hello.txt

Le contenu de la hello.txtvolonté, sans surprise, sera

Hello, world!

Disons que nous avons un autre programme appelé greet, similaire à helloworld, qui vous salue avec une donnée name:

#include  #include  int main() { // Initialize an array to hold the name. char name[20]; // Read a string and save it to name. scanf("%s", name); // Print the greeting. printf("Hello, %s!", name); return EXIT_SUCCESS; }

Au lieu de lire à partir du clavier, nous pouvons rediriger stdinpour lire à partir d'un fichier à l'aide de l' <outil:

# Write a file containing a name. echo Kamala > name.txt # This will read the name from the file and print out the greeting to the screen. ./greet  Hello, Kamala! # If you wanted to also write the greeting to a file, you could do so using ">".

Remarque: ces opérateurs de redirection sont dans bashdes shells similaires.

La vraie affaire

Les méthodes ci-dessus ne fonctionnaient que pour les cas les plus élémentaires. Si vous vouliez faire des choses plus grandes et meilleures, vous voudrez probablement travailler avec des fichiers depuis C plutôt que via le shell.

Pour ce faire, vous utiliserez une fonction appelée fopen. Cette fonction prend deux paramètres de chaîne, le premier étant le nom du fichier et le second étant le mode.

Les modes sont essentiellement des permissions, donc rpour la lecture, wpour l'écriture, apour l'ajout. Vous pouvez également les combiner, ce rwqui signifie que vous pouvez lire et écrire dans le fichier. Il existe d'autres modes, mais ce sont les plus couramment utilisés.

Une fois que vous avez un FILEpointeur, vous pouvez utiliser fondamentalement les mêmes commandes IO que vous auriez utilisées, sauf que vous devez les préfixer fet le premier argument sera le pointeur de fichier. Par exemple, printfla version du fichier de est fprintf.

Voici un programme appelé greetingsqui lit un dans un fichier contenant une liste de noms et écrit les salutations dans un autre fichier:

#include  #include  int main() { // Create file pointers. FILE *names = fopen("names.txt", "r"); FILE *greet = fopen("greet.txt", "w"); // Check that everything is OK. if (!names || !greet) { fprintf(stderr, "File opening failed!\n"); return EXIT_FAILURE; } // Greetings time! char name[20]; // Basically keep on reading untill there's nothing left. while (fscanf(names, "%s\n", name) > 0) { fprintf(greet, "Hello, %s!\n", name); } // When reached the end, print a message to the terminal to inform the user. if (feof(names)) { printf("Greetings are done!\n"); } return EXIT_SUCCESS; }

Supposons qu'il names.txtcontienne ce qui suit:

Kamala Logan Carol

Ensuite, après avoir exécuté greetingsle fichier greet.txtcontiendra:

Hello, Kamala! Hello, Logan! Hello, Carol!