Entrée et sortie en langage C

29 Aug 2019 29 Aug 2019 14949 vues ESSADDOUKI Mostafa 8 min de lecture

Entrées / Sorties en C

Définition — Entrée / Sortie Une entrée consiste à fournir des données au programme (clavier, fichier, réseau). Une sortie consiste à afficher ou enregistrer un résultat (écran, fichier, imprimante). En C, toutes les fonctions d'E/S sont regroupées dans l'en-tête <stdio.h> (Standard Input/Output).
CatégorieFonctionsUsage
E/S formatéesprintf(), scanf()Affichage/lecture avec spécificateurs de format
E/S de caractèresputchar(), getchar()Un seul caractère à la fois
E/S de chaînesputs(), 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 standardPointeurPériphérique par défautUsage typique
Entrée standardstdinClavierscanf(), getchar()
Sortie standardstdoutÉcranprintf(), putchar()
Erreur standardstderrÉcranfprintf(stderr, ...)
Redirection des fluxCes flux peuvent être redirigés depuis le terminal sans modifier le code source :
./programme < entree.txt       # stdin redirigé depuis un fichier
./programme > sortie.txt       # stdout redirigé vers un fichier
./programme 2> erreurs.txt     # stderr redirigé vers un fichier

2. 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 %.

TypeSpécificateurExemple printfModificateurs courants
int%dprintf("%d", 42)%5d (largeur 5), %-5d (aligné gauche)
unsigned int%uprintf("%u", 42u)
float%fprintf("%f", 3.14f)%.2f (2 décimales)
double%lf (scanf) / %f (printf)printf("%lf", 3.14)%.4lf
long double%Lfprintf("%Lf", val)
char%cprintf("%c", 'A')
char * (chaîne)%sprintf("%s", "Meknes")%10s, %.5s (tronquer)
long int%ldprintf("%ld", val)
long long int%lldprintf("%lld", val)
Hexadécimal%x / %Xprintf("%x", 255)ff%08x (8 chiffres, zéros)
Astuce — Largeur et précision dans les spécificateurs La syntaxe complète d'un spécificateur est %[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()


Syntaxe C
/* Affichage formaté */
printf("format", variable1, variable2, ...);

/* Lecture formatée — noter l'opérateur & devant chaque variable */
scanf("format", &variable1, &variable2, ...);
Rôle de l'opérateur & 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;
}
Sortie
Entrez un entier : 2
a = 2
Entrez un réel : 3.5
b = 3.50
Entrez un caractère : f
d = f
Attention — Le saut de ligne résiduel avec %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;
}
Sortie
Entrez deux entiers et un réel (ex: 2 5 3.5) : 2 5 3.5
a = 2 | b = 5 | c = 3.50
Limiter la largeur de lecture On peut limiter le nombre de caractères lus en ajoutant une largeur dans le spécificateur. Si l'utilisateur saisit 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() / 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.

Syntaxe C
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;
}
Sortie
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;
}
Sortie
Saisir une ligne : Bonjour
Bonjour
Pourquoi 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() / gets() / fgets() 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;
}
Sortie
Saisir votre nom complet : Mohamed Amine
Votre nom est : Mohamed Amine

Comparaison des fonctions de lecture

Critèrescanf("%s")gets()fgets()
Lit les espacesNon (s'arrête à l'espace)OuiOui
Limite la tailleAvec %NsNonOui (paramètre n)
Conserve '\n'NonNonOui (à supprimer manuellement)
SécuritéPartielleDangereuse — supprimée en C11Recommandée
DisponibilitéC89+Supprimée en C11C89+
Danger — 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

FonctionEn-têteRôlePoint clé
printf()<stdio.h>Affichage formaté sur stdoutSpécificateurs %d %f %c %s
scanf()<stdio.h>Lecture formatée depuis stdinOpérateur & obligatoire
putchar()<stdio.h>Affiche un caractère sur stdoutRetourne le caractère affiché
getchar()<stdio.h>Lit un caractère depuis stdinRetourne 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 tailleRemplace gets() — sûre
gets()<stdio.h>Lit une ligne sans limiteSupprimée C11 — ne jamais utiliser

Discussion (0)

Soyez le premier à laisser un commentaire !

Laisser un commentaire

Votre commentaire sera visible après modération.