Lecture au clavier et entrées standard en langage C

@joekakone

Joseph Konka @joekakone

03/03/2026 · 7 min

Apprenez à saisir des données au clavier en C avec scanf(), l'opérateur d'adresse &, getchar() et la gestion des pièges classiques du tampon d'entrée (buffer).

Après avoir appris à transmettre des messages vers l'écran, découvrons comment rendre nos programmes interactifs en lisant des données saisies au clavier par l'utilisateur.

En langage C, la lecture sur l'entrée standard (stdin) repose principalement sur la fonction scanf() et la fonction getchar(), toutes deux déclarées dans <stdio.h>.


1. La fonction scanf() et le rôle vital de l'opérateur &#

La fonction scanf() (scan formatted) analyse le flux de saisie au clavier et stocke la valeur convertie dans une case mémoire réservée à une variable.

Exemple de saisie élémentaire
#include <stdio.h>

int main(void)
{
    int age = 0;

    printf("Entrez votre age : ");
    // L'esperluette & indique l'adresse mémoire de la variable 'age'
    scanf("%d", &age);

    printf("Vous avez declare avoir %d ans.\n", age);
    return 0;
}

Pourquoi l'esperluette & est-elle obligatoire ?#

En C, lorsqu'une variable est passée en paramètre à une fonction sans préfixe, la fonction ne reçoit qu'une copie de sa valeur. Si scanf() travaillait sur une copie, elle modifierait cette copie temporaire et votre variable originale resterait inchangée !

En préfixant le nom de la variable par & (l'opérateur d'adresse), vous transmettez à scanf() l'adresse de la case mémoire où réside la variable. La fonction peut ainsi aller directement écrire la valeur saisie dans la mémoire vive.

[!WARNING] Oublier le symbole & devant une variable scalaire dans scanf() est l'erreur numéro un des débutants en C : le programme compilera parfois avec un simple avertissement mais plantera immédiatement à l'exécution avec une redoutable erreur de segmentation (Segmentation Fault).


2. Spécificateurs de format pour scanf()#

Attention à la subtilité fondamentale entre float et double lors de la lecture :

Type attendu Spécificateur scanf Syntaxe d'appel
int %d scanf("%d", &entier);
float %f scanf("%f", &flottant);
double %lf (long float) scanf("%lf", &flottant_double);
char %c scanf("%c", &caractere);
char[] (chaîne) %s (sans espaces) scanf("%29s", tableau_char); (pas de & car le nom d'un tableau est déjà une adresse)

3. Saisie d'un caractère avec getchar()#

Pour lire un caractère unique au clavier, la fonction getchar() est une alternative élégante et directe :

Saisie d'un caractère unique
#include <stdio.h>

int main(void)
{
    printf("Entrez votre initiale : ");
    char initiale = getchar();

    printf("Initiale enregistree : '%c'\n", initiale);
    return 0;
}

4. Le piège classique du tampon d'entrée (Buffer)#

Lorsque vous tapez un nombre au clavier (par exemple 25) puis appuyez sur Entrée, vous envoyez deux éléments dans le tampon de mémoire du clavier : 1. Le nombre 25 2. Le caractère invisible de saut de ligne \n produit par la touche Entrée.

scanf("%d", ...) consomme le nombre 25, mais laisse traîner le \n dans le tampon ! Si vous tentez immédiatement après de lire un caractère avec scanf("%c", ...) ou getchar(), la fonction lira instantanément le \n résiduel sans attendre que l'utilisateur n'ait eu le temps de taper quoi que ce soit.

Illustration du problème et solution élégante
#include <stdio.h>

int main(void)
{
    int annee;
    char mention;

    printf("Annee d'etudes (1 a 5) : ");
    scanf("%d", &annee);

    // ASTUCE : L'espace avant %c force scanf a ignorer tous les blancs et le '\n' residuel
    printf("Mention souhaitee (A/B/C) : ");
    scanf(" %c", &mention);

    printf("Resultat : Annee %d | Mention %c\n", annee, mention);
    return 0;
}

Méthode universelle pour vider le tampon d'entrée#

Pour nettoyer rigoureusement le tampon après une saisie, on consomme tous les caractères restants jusqu'au saut de ligne :

void ViderBuffer(void)
{
    int c;
    while ((c = getchar()) != '\n' && c != EOF)
    {
        // On jette les caractères résiduels
    }
}

5. Saisir des phrases avec espaces : la supériorité de fgets()#

L'instruction scanf("%s", texte) s'arrête au premier espace rencontré. Pour lire une ligne complète (par exemple le prénom et le nom d'un étudiant avec espaces), on utilise fgets() :

Lecture securisee de texte avec espaces
#include <stdio.h>
#include <string.h>

#define TAILLE_MAX 50

int main(void)
{
    char nom_complet[TAILLE_MAX];

    printf("Entrez votre nom et prenom : ");
    // Lit jusqu'à TAILLE_MAX-1 caractères depuis l'entrée standard stdin
    if (fgets(nom_complet, sizeof(nom_complet), stdin) != NULL)
    {
        // Supprime le saut de ligne final éventuel capté par fgets
        nom_complet[strcspn(nom_complet, "\n")] = '\0';
        printf("Bienvenue, %s !\n", nom_complet);
    }

    return 0;
}

[!NOTE] La fonction historique gets() a été officiellement bannie de la norme C (supprimée depuis C11) car elle est incapable de limiter la taille de la saisie, provoquant de gravissimes failles de dépassement de tampon (buffer overflow). Utilisez toujours fgets() !


6. Mise en pratique : Calculateur de moyenne#

Énoncé : Concevez un programme qui demande à un étudiant son nom, son âge et deux notes d'examens (coefficients 2 et 3), puis calcule et affiche sa moyenne pondérée avec deux décimales.

??? tip "Solution complète"

#include <stdio.h>

int main(void)
{
    int age;
    float note1, note2;
    const int coef1 = 2;
    const int coef2 = 3;

    printf("--- FORMULAIRE D'EVALUATION ACADEMIQUE ---\n");
    printf("Age de l'etudiant : ");
    scanf("%d", &age);

    printf("Note d'examen 1 (sur 20) : ");
    scanf("%f", &note1);

    printf("Note d'examen 2 (sur 20) : ");
    scanf("%f", &note2);

    float moyenne = (note1 * coef1 + note2 * coef2) / (float)(coef1 + coef2);

    printf("\n------------------------------------------\n");
    printf("Etudiant age de %d ans\n", age);
    printf("Moyenne ponderee : %.2f / 20\n", moyenne);

    if (moyenne >= 10.0f)
    {
        printf("Decision : ADMIS(E)\n");
    }
    else
    {
        printf("Decision : AJOURNE(E)\n");
    }
    printf("------------------------------------------\n");

    return 0;
}


Vous savez désormais communiquer dans les deux sens avec l'utilisateur. Approfondissons maintenant la gestion de la mémoire avec les variables, types fondamentaux et constantes en langage C.

Commentaires

Inscrivez-vous à une formation complète

Voir le catalogue