Les entrées-sorties de haut niveau intègrent deux mécanismes distincts :
L'acquisition d'un nouveau flot s'effectue par l'appel à la fonction fopen. La fonction fclose permet de le fermer.
Syntaxe
FILE *fopen(const char *file, const char *type); int fclose(const FILE *flot);La fonction fopen retourne un pointeur sur le 1
Un pointeur NULL, pseudo-constante définie comme (void *)0 dans stdio.h, indique une fin anormale.
La fonction fclose retourne 0 en cas de succès, -1 sinon.
Le 2 argument de la fonction fopen indique le mode d'ouverture
du fichier. (r,w,a)
Certains systèmes font la distinction entre les fichiers texte
et binaire. Pour manipuler ces derniers, il suffit de rajouter
le caractère b dans la chaîne indiquant le mode d'ouverture.
Sous UNIX, il est ignoré car il n'existe aucune différence
entre un fichier binaire et un fichier de données quelconques.
Exemple
#include <stdio.h> main() { FILE * flot; if ((flot = fopen("donnees", "r")) == NULL) { fprintf(stderr, "Erreur a l'ouverture\n"); exit(1); } fclose(flot); }
Les fonctions getc, fgetc et putc, fputc permettent de lire ou écrire un caractère sur un flot donné.
getc et putc sont des pseudo-fonctions.
Syntaxe
int getc(FILE *Stream) int fgetc(FILE *Stream) int putc(int c, FILE *Stream) int fputc(int c, FILE *Stream)Il existe deux pseudo-fonctions supplémentaires :
Deux pseudo-fonctions feof et ferror, définies dans le fichier stdio.h, permettent de tester, respectivement, la fin de fichier et une éventuelle erreur d'entrée-sortie sur le flot passé en argument.
Dans le cas d'une entrée-sortie au terminal, c'est le retour chariot qui provoque l'envoi au programme de la mémoire tampon rattachée au pilote /dev/tty.
Exemple
#include <stdio.h> main() { char c; <=== Attention Erreur ! ---------------- while ((c = getchar()) != EOF) putchar(c); }
Les fonctions getw et putw permettent de lire ou écrire des mots.
Syntaxe
int getw(FILE *flot) int putw(int c, FILE *flot)
Exemple
#include <stdio.h> #define DIM 100 main() { FILE *flot; int tab[DIM]; int i; if ((flot = fopen("resultat", "w")) == NULL) { perror("fopen"); exit(1); } for (i=0; i i < DIM; i++) { tab[i] = i*i; putw(tab[i], flot); } fclose(flot); }
Les fonctions gets, fgets et puts, fputs permettent de lire et écrire des chaînes de caractères.
Syntaxe
char *gets(char *string) int puts(char *string) char *fgets(char *string, int nombre, FILE *flot) int fputs(char *string, FILE *flot)
Exemple
#include <stdio.h> main() { char *mus1 = "Wolfgang Amadeus Mozart\n"; char *mus2 = "Ludwig van Beethoven\n"; char buffer[BUFSIZ+1]; FILE *f; if ((f = fopen("musiciens", "w")) == NULL) { perror("fopen"); exit(1); } fputs(mus1, f); fputs(mus2, f); fclose(f); if ((f = fopen("musiciens", "r")) == NULL) { perror("fopen"); exit(2); } while (fgets(buffer, sizeof(buffer), f)) fputs(buffer, stdout); fclose(f); puts("\nExecution terminee."); }
Les fonctions fread et fwrite permettent de lire et d'écrire des blocs de données tels des structures ou des tableaux.
Syntaxe
size_t fread(void *p, size_t t, size_t n, FILE *f) size_t fwrite(void *p, size_t t, size_t n, FILE *f)
Exemple
#include <stdio.h> #define NbElt(t) ( sizeof t / sizeof t[0] ) main() { typedef struct { int n; float t[10]; char c; } Donnee; Donnee s1 = { 1, { 1., 2., 3.}, 'a'}; Donnee s2[] = { {4, {10., 32., 3.}, 'z'}, {5, { 2., 11., 2., 4.}, 'h'} }; FILE *f, *f_sauve; Donnee s; if ((f = fopen("donnee", "w")) == NULL) perror("fopen"), exit(1); fwrite(&s1, sizeof(Donnee), 1, f); fwrite( s2, sizeof(Donnee), NbElt(s2), f); fclose(f); if ((f = fopen("donnee", "r")) == NULL || (f_sauve = fopen("sauvegarde", "w")) == NULL) perror("fopen"), exit(2); fread(&s, sizeof(Donnee), 1, f); while (!feof(f)) { fwrite(&s, sizeof(Donnee), 1, f_sauve); fread(&s, sizeof(Donnee), 1, f); } fclose(f); fclose(f_sauve); }
Par défaut, les fonctions précédentes travaillent en mode séquentiel. Chaque lecture ou écriture s'effectue à partir d'une position courante, et incrémente cette position du nombre de caractères lus ou écrits.
Les fonctions fseek et ftell permettent, respectivement, de modifier et récupérer la position courante.
int fseek(FILE *f, long decalage, int position); long ftell(FILE *f);
La fonction ftell retourne la position courante en octets.
La fonction fseek permet de la modifier :
#include <stdio.h> main(int argc, char **argv) { FILE *f; void usage(char *s); if (argc != 2) usage(argv[0]); if ((f = fopen(argv[1], "r")) == NULL) { perror("fopen"); exit(2); } fseek(f, 0L, SEEK_END); printf("Taille(octets) : %d\n", ftell(f)); fclose(f); } void usage(char *s) { fprintf(stderr, "usage : %s fichier\n", s); exit(1); }
Les fonctions scanf, fscanf, sscanf et printf, fprintf, sprintf permettent d'effectuer des entrées-sorties de données avec conversions.
Syntaxe
int scanf(const char *format [, ...]) int fscanf(FILE *f, const char *format [, ...]) int sscanf(const char *buffer, const char *format [, ...]) int printf(const char *format [, ...]) int fprintf(FILE *f, const char *format [, ...]) int sprintf(const char *buffer, const char *format [, ...])
Le paramètre format désigne une chaîne de caractères comprenant :
Une spécification de conversion est constituée du caractère %, suivie dans l'ordre :
printf("|%d|\n", 1234); |1234| printf("|%+d|\n", 1234); |+1234| printf("|%10d|\n", 1234); | 1234| printf("|%x|\n", 0x56ab); |56ab| printf("|%#x|\n", 0x56ab); |0x56ab| printf("|%X|\n", 0x56ab); |56AB| printf("|%#X|\n", 0x56ab); |0X56AB| printf("|%f|\n",1.234567890123456789e5); |123456.789012| printf("|%.4f|\n",1.234567890123456789e5); |123456.7890| printf("|%15.4f|\n",1.234567890123456789e5); | 123456.7890| printf("|%e|\n",1.234567890123456789e5); |1.234568e+05| printf("|%.18e|\n",1.234567890123456789e5); ~~~~~~~~~~|1.234567890123456700e+05| printf("|%.4g|\n",1.234567890123456789e-5); |1.235e-05| printf("|%.4g|\n",1.234567890123456789e-3); |0.001235|
Ces fonctions permettent d'effectuer des entrées formatées. Les données lues sont converties suivant les spécifications de conversions indiquées dans la chaîne format, puis stockées dans les arguments successifs fournis à sa suite. Ces arguments doivent être des pointeurs.
La valeur retournée correspond au nombre d'arguments correctement affectés. La chaîne format peut contenir :
Chaque champ est défini comme une chaîne de caractères qui s'étend soit :
Les arguments correspondant aux spécifications :
De même les spécifications e, f, g peuvent être précédées de la lettre l pour référencer un double *.
Exemples
#include <stdio.h> main() { int i; float x, y; char buffer[BUFSIZ]; char *p = "12/11/94"; int jour, mois, annee; scanf("%d%f%f%*c", &i, &x, &y); printf("i = %d, x = %f, y = %f\n", i, x, y); scanf("%[^\n]%*c", buffer); while (!feof(stdin)) { fprintf(stderr, "%s\n", buffer); scanf("%[^\n]%*c", buffer); } sscanf(p, "%d/%d/%d", &jour, &mois, &annee); printf("jour : %d\n", jour); printf("mois : %d\n", mois); printf("annee : %d\n", annee); }
La fonction freopen permet de redéfinir un flot déjà initialisé. Elle est principalement utilisée avec les flots stdin, stdout, stderr, ce qui correspond à une redirection d'entrées-sorties.
La fonction fflush permet de forcer le vidage de la mémoire tampon associée à un flot en sortie. Sur un flot en entrée l'effet est imprévisible.
Syntaxe
FILE *freopen(char *fichier, char *mode, FILE *flot); int fflush(FILE *flot);
Exemple
#include <stdio.h> main(int argc, char **argv) { void usage(char *s); if (argc != 2) usage(argv[0]); if (freopen(argv[1], "w", stdout) == NULL) { perror("freopen"); exit(2); } printf("Ce message est redirige "); printf("dans le fichier "); printf("dont le nom est "); printf("passe en argument.\n"); } void usage(char *s) { fprintf(stderr, "usage : %s fichier\n", s); exit(1); }