Entrées / Sorties en C
<stdio.h> (Standard Input/Output).| Catégorie | Fonctions | Usage |
|---|---|---|
| E/S formatées | printf(), scanf() | Affichage/lecture avec spécificateurs de format |
| E/S de caractères | putchar(), getchar() | Un seul caractère à la fois |
| E/S de chaînes | puts(), gets() / fgets() | Chaîne entière (avec espaces) |
1. Fichiers standard
En C, tout périphérique est traité comme un fichier. Trois flux standard sont ouverts automatiquement au démarrage de tout programme :
| Fichier standard | Pointeur | Périphérique par défaut | Usage typique |
|---|---|---|---|
| Entrée standard | stdin | Clavier | scanf(), getchar() |
| Sortie standard | stdout | Écran | printf(), putchar() |
| Erreur standard | stderr | Écran | fprintf(stderr, ...) |
./programme < entree.txt # stdin redirigé depuis un fichier
./programme > sortie.txt # stdout redirigé vers un fichier
./programme 2> erreurs.txt # stderr redirigé vers un fichier2. Spécificateurs de format
Un spécificateur de format indique au compilateur le type de la donnée à lire ou à afficher. Il commence toujours par le caractère %.
| Type | Spécificateur | Exemple printf | Modificateurs courants |
|---|---|---|---|
int | %d | printf("%d", 42) | %5d (largeur 5), %-5d (aligné gauche) |
unsigned int | %u | printf("%u", 42u) | — |
float | %f | printf("%f", 3.14f) | %.2f (2 décimales) |
double | %lf (scanf) / %f (printf) | printf("%lf", 3.14) | %.4lf |
long double | %Lf | printf("%Lf", val) | — |
char | %c | printf("%c", 'A') | — |
char * (chaîne) | %s | printf("%s", "Meknes") | %10s, %.5s (tronquer) |
long int | %ld | printf("%ld", val) | — |
long long int | %lld | printf("%lld", val) | — |
| Hexadécimal | %x / %X | printf("%x", 255) → ff | %08x (8 chiffres, zéros) |
%[drapeaux][largeur][.précision]type:printf("%8d", 42); /* 42 — largeur 8, aligné droite */
printf("%-8d", 42); /* 42 — largeur 8, aligné gauche */
printf("%08d", 42); /* 00000042 — rempli de zéros */
printf("%.2f", 3.14159);/* 3.14 — 2 chiffres après la virgule */
printf("%8.2f", 3.14159);/* 3.14 — largeur 8, 2 décimales */3. printf() et scanf()
/* Affichage formaté */
printf("format", variable1, variable2, ...);
/* Lecture formatée — noter l'opérateur & devant chaque variable */
scanf("format", &variable1, &variable2, ...);& dans scanf() L'opérateur & fournit l'adresse mémoire de la variable. Sans lui, scanf() recevrait la valeur (inconnue) de la variable plutôt que son adresse — il ne pourrait pas écrire dedans et le programme produirait un comportement indéfini.Exemple n°1 — Lire et afficher différents types
#include <stdio.h>
int main(void)
{
int a;
float b;
char d;
/* Lecture d'un entier */
printf("Entrez un entier : ");
scanf("%d", &a);
printf("a = %d\n", a);
/* Lecture d'un réel */
printf("Entrez un réel : ");
scanf("%f", &b);
printf("b = %.2f\n", b);
/* Lecture d'un caractère */
printf("Entrez un caractère : ");
scanf(" %c", &d); /* espace avant %c pour ignorer le \n résiduel */
printf("d = %c\n", d);
return 0;
}Entrez un entier : 2 a = 2 Entrez un réel : 3.5 b = 3.50 Entrez un caractère : f d = f
%c Après un scanf("%d", ...), la touche Entrée laisse un caractère '\n' dans le tampon. Un scanf("%c", ...) suivant lirait ce '\n' au lieu du caractère attendu. La solution est d'ajouter un espace avant %cpour consommer les espaces blancs résiduels :scanf("%d", &n);
scanf(" %c", &c); /* espace avant %c — consomme le \n résiduel */Exemple n°2 — Lecture et affichage de plusieurs valeurs
#include <stdio.h>
int main(void)
{
int a, b;
float c;
printf("Entrez deux entiers et un réel (ex: 2 5 3.5) : ");
scanf("%d %d %f", &a, &b, &c);
printf("a = %d | b = %d | c = %.2f\n", a, b, c);
return 0;
}Entrez deux entiers et un réel (ex: 2 5 3.5) : 2 5 3.5 a = 2 | b = 5 | c = 3.50
42 et que le format est %1d, seul le chiffre 4sera lu :int x;
scanf("%1d", &x); /* saisie : 42 → x vaut 4 */
char nom[6];
scanf("%5s", nom); /* lit au plus 5 caractères */4. getchar() et putchar()
getchar() lit un seul caractère depuis stdin et le retourne sous forme d'entier (int). putchar() affiche un seul caractère sur stdout. Ces fonctions sont adaptées au traitement caractère par caractère, notamment dans des boucles.int c = getchar(); /* lit un caractère, retourne int (ou EOF) */
putchar(c); /* affiche le caractère */Exemple n°3 — Lire et afficher un caractère
#include <stdio.h>
int main(void)
{
int c;
printf("Saisir un caractère : ");
c = getchar();
printf("Voici votre caractère : ");
putchar(c);
putchar('\n');
return 0;
}Saisir un caractère : A Voici votre caractère : A
Exemple n°4 — Copier une ligne caractère par caractère
#include <stdio.h>
int main(void)
{
int c;
printf("Saisir une ligne : ");
while ((c = getchar()) != '\n' && c != EOF)
putchar(c);
putchar('\n');
return 0;
}Saisir une ligne : Bonjour Bonjour
getchar() retourne int et non char ? getchar() peut retourner la valeur spéciale EOF (−1) pour signaler la fin de fichier. Un char ne peut pas représenter −1 de façon portable — déclarer la variable de réception comme int est donc obligatoire.5. gets() / fgets() et puts()
puts() affiche une chaîne sur stdout suivie d'un saut de ligne automatique. gets() lit une ligne entière depuis stdin jusqu'au '\n' ou EOF. fgets() fait la même chose mais en limitant le nombre de caractères lus — c'est la version sûre recommandée.Exemple n°5 — Lire et afficher un nom (avec fgets)
#include <stdio.h>
#include <string.h>
int main(void)
{
char nom[50];
printf("Saisir votre nom complet : ");
fgets(nom, sizeof(nom), stdin); /* lecture sécurisée */
/* fgets conserve le \n — le supprimer si nécessaire */
nom[strcspn(nom, "\n")] = '\0';
printf("Votre nom est : ");
puts(nom); /* affiche + \n automatique */
return 0;
}Saisir votre nom complet : Mohamed Amine Votre nom est : Mohamed Amine
Comparaison des fonctions de lecture
| Critère | scanf("%s") | gets() | fgets() |
|---|---|---|---|
| Lit les espaces | Non (s'arrête à l'espace) | Oui | Oui |
| Limite la taille | Avec %Ns | Non | Oui (paramètre n) |
Conserve '\n' | Non | Non | Oui (à supprimer manuellement) |
| Sécurité | Partielle | Dangereuse — supprimée en C11 | Recommandée |
| Disponibilité | C89+ | Supprimée en C11 | C89+ |
gets() est supprimée en C11 gets() ne vérifie pas la taille du tampon de destination. Un utilisateur peut saisir plus de caractères qu'il n'y a de place, provoquant un dépassement de tampon (buffer overflow) exploitable pour des attaques. Elle a été officiellement supprimée de la norme C11. Toujours utiliser fgets()à la place :char nom[20];
/* Dangereux — à ne jamais utiliser */
gets(nom);
/* Correct et sécurisé */
fgets(nom, sizeof(nom), stdin);Récapitulatif
| Fonction | En-tête | Rôle | Point clé |
|---|---|---|---|
printf() | <stdio.h> | Affichage formaté sur stdout | Spécificateurs %d %f %c %s |
scanf() | <stdio.h> | Lecture formatée depuis stdin | Opérateur & obligatoire |
putchar() | <stdio.h> | Affiche un caractère sur stdout | Retourne le caractère affiché |
getchar() | <stdio.h> | Lit un caractère depuis stdin | Retourne int (gère EOF) |
puts() | <stdio.h> | Affiche une chaîne + '\n' | Plus simple que printf("%s\n") |
fgets() | <stdio.h> | Lit une ligne avec limite de taille | Remplace gets() — sûre |
gets() | <stdio.h> | Lit une ligne sans limite | Supprimée C11 — ne jamais utiliser |
Discussion (0)
Soyez le premier à laisser un commentaire !
Laisser un commentaire
Votre commentaire sera visible après modération.