HOWTO · C
Utiliser la redirection de fichiers en C
Cet article montre comment utiliser la redirection de fichiers dans C
Sur cette page
Pour rediriger depuis la ligne de commande l’entrée ou la sortie d’un programme C, utilisez les opérateurs du shell <, > et >>. Le shell relie les flux standard du programme à des fichiers ; le code C peut plutôt ouvrir un fichier nommé avec fopen ou modifier un flux standard avec freopen. Ces méthodes permettent toutes de gérer des données, mais correspondent à des opérations différentes.
Comprendre la redirection de fichiers en C
Un processus C dispose dès son démarrage de trois flux standard : stdin pour l’entrée, stdout pour la sortie normale et stderr pour les messages de diagnostic. En général, le shell les relie au terminal. La redirection modifie ces connexions au lancement du programme. Celui-ci peut donc continuer à appeler fgets, printf ou fprintf(stderr, ...) sans savoir si un flux est relié à un terminal ou à un fichier.
À l’inverse, fopen renvoie un FILE * distinct que votre code peut lire ou écrire directement. Utilisez cette fonction si le programme doit choisir entre plusieurs fichiers, en gérer plusieurs à la fois ou contrôler leur durée de vie. Préférez la redirection du shell lorsque la personne qui lance le programme doit choisir la source d’entrée ou la destination de sortie.
Rediriger la sortie du programme avec > et »
Ce petit programme écrit une ligne dans stdout :
Exécutez cet exemple :
Le code et les libellés ou sorties affichés dans cette section restent en anglais.
#include <stdio.h>
int main(void) {
puts("Report complete");
return 0;
}
La ligne du programme est envoyée vers stdout ; aucun relevé d’exécution n’est fourni avec cet exemple. Après l’avoir compilé sous le nom report, lancez ./report > report.txt pour créer ou remplacer report.txt. Pour ajouter le texte à la fin du fichier, utilisez ./report >> report.txt. L’opérateur > tronque la destination existante avant le démarrage du programme, tandis que >> écrit à la fin. La syntaxe du shell et les commandes de compilation disponibles varient selon la plateforme. Le code et ses libellés visibles restent en anglais.
C’est le shell qui ouvre la destination redirigée. Si cette ouverture échoue, le shell signale le problème et, en général, ne lance pas le programme. Celui-ci ne peut pas détecter cet échec comme une erreur de fopen, puisqu’il n’a pas ouvert lui-même la destination. Pour enregistrer les diagnostics dans un fichier distinct, utilisez ./report > report.txt 2> errors.txt ; 2> redirige le descripteur de fichier conventionnel utilisé par stderr.
Rediriger l’entrée du programme avec <
Lisez depuis stdin lorsque la personne qui lance le programme doit choisir la source d’entrée. Ce programme lit des lignes jusqu’à ce que le fichier redirigé atteigne la fin :
Le code et les libellés ou sorties affichés dans cette section restent en anglais.
#include <stdio.h>
int main(void) {
char line[128];
while (fgets(line, sizeof line, stdin) != NULL) {
if (fputs(line, stdout) == EOF) {
perror("writing stdout");
return 1;
}
}
if (ferror(stdin)) {
perror("reading stdin");
return 1;
}
return 0;
}
Compilez-le sous le nom copy-input, puis lancez ./copy-input < input.txt. fgets lit au maximum un caractère de moins que la capacité du tampon, ajoute un caractère nul de fin et conserve le caractère de nouvelle ligne s’il en lit un. Une ligne longue peut donc être renvoyée en plusieurs morceaux. Après la boucle, vérifiez ferror pour distinguer une erreur de lecture d’une fin de fichier normale. Le comportement de l’exemple découle des opérations sur les flux C qui y figurent ; aucune sortie observée n’est fournie. Le code et ses libellés visibles restent en anglais.
Rediriger les flux standard dans un programme C
Lorsque le programme doit lui-même choisir une destination, freopen peut rouvrir un flux standard. Cette fonction prend un chemin, un mode tel que "w" ou "a", puis le flux à rouvrir. Par exemple, freopen("run.log", "a", stdout) envoie la sortie standard suivante à la fin de run.log. Vérifiez la valeur renvoyée avant d’écrire : la fonction renvoie NULL si la réouverture échoue. Cela modifie le flux du processus, contrairement à fopen, qui fournit un flux supplémentaire sans toucher à stdout.
Choisissez cette méthode lorsque la redirection fait partie du comportement du programme. Si la personne qui le lance doit choisir la destination, laissez stdout inchangé et utilisez > ou >>. freopen fait partie du C standard, mais le comportement précis d’un flux après l’échec de sa réouverture peut dépendre de l’implémentation. Traitez le résultat NULL et ne poursuivez pas comme si la redirection avait réussi.
Gérer les erreurs et choisir la bonne méthode
Vérifiez chaque opération susceptible d’échouer. Testez le résultat de fopen et de freopen avant d’utiliser le flux renvoyé, contrôlez les fonctions de sortie telles que fprintf ou fputs, et vérifiez fclose lorsque vous devez vous assurer que la sortie mise en tampon a bien été écrite dans le fichier. Dans une boucle de lecture, un résultat NULL de fgets peut indiquer une fin de fichier ou une erreur de lecture ; consultez ferror pour faire la différence. perror peut afficher un message du système d’exploitation pour une erreur associée à la valeur courante de errno.
Ne dimensionnez pas un tampon destiné à lire des lignes en fonction de la longueur en octets annoncée pour le fichier : l’entrée peut provenir d’un tube ou d’un terminal, et une ligne peut dépasser la capacité choisie. Un tampon de taille fixe utilisé avec plusieurs appels à fgets convient si le traitement par morceaux est acceptable. Pour lire une ligne logique de longueur arbitraire, agrandissez un tampon à mesure que les morceaux arrivent et vérifiez les limites d’allocation et de calcul, ou utilisez une fonction de lecture propre à une plateforme en précisant ses limites de portabilité.
Choisissez la redirection du shell pour relier les flux standard d’une exécution, fopen pour gérer un fichier supplémentaire en C, et freopen lorsque le programme doit lui-même remplacer un flux standard. Gardez les diagnostics sur stderr lorsque la sortie normale est redirigée, et vérifiez les erreurs à la couche qui effectue l’opération.