Entrées et sorties en C : fonctions, formats et pièges courants

Le fichier d'en-tête <stdio.h> fournit deux primitives élémentaires pour manipuler l'entrée et la sortie standard : int getchar(void) et int putchar(int c). La première lit un caractère depuis stdin et la seconde écrit un caractère sur stdout. Comme le flux peut atteindre sa fin ou rencontrer une erreur, le retour de getchar est un int capable de représenter la valeur EOF.

#include <stdio.h>

int main(void)
{
    int c;

    printf("Saisissez un caractère : ");
    c = getchar();

    if (c == EOF) {
        printf("Aucune donnée lue.\n");
        return 1;
    }

    printf("Reçu : ");
    putchar(c);
    putchar('\n');

    return 0;
}

Lecture sécurisée d'une ligne avec fgets

La fonction gets est à éviter car elle ne limite pas la taille du buffer. En pratique, on utilise fgets, qui requiert la longueur du tableau et retourne la ligne inclunat le caractère de fin de ligne :

#include <stdio.h>
#include <string.h>

int main(void)
{
    char tampon[128];

    printf("Entrez une ligne : ");
    if (fgets(tampon, sizeof(tampon), stdin) == NULL) {
        return 1;
    }

    /* retirer le '\n' final si présent */
    size_t n = strlen(tampon);
    if (n > 0 && tampon[n - 1] == '\n') {
        tampon[n - 1] = '\0';
    }

    puts(tampon);

    return 0;
}

fgets renvoie le pointeur vers le buffer en cas de succès, ou NULL si la fin du fichier ou une erreur est atteinte avant qu'un caractère ne soit lu.

Saisie formatée avec scanf

int scanf(const char *format, ...) analyse l'entrée selon une chaîne de format. Elle retourne le nombre de conversions effectuées avec succès, ou EOF en cas d'erreur ou de fin de fichier. L'exemple ci-dessous lit un entier, un caractère et un mot, en vidant le tampon entre chaque étape pour éviter que le retour à la ligne ne perturbe les lectures suivantes :

#include <stdio.h>

static void purger(void)
{
    int c;
    while ((c = getchar()) != '\n' && c != EOF) { }
}

int main(void)
{
    int quantite;
    char symbole;
    char nom[40];

    printf("Quantité : ");
    scanf("%d", &quantite);
    purger();

    printf("Symbole : ");
    scanf(" %c", &symbole);
    purger();

    printf("Nom (sans espaces) : ");
    scanf("%39s", nom);
    purger();

    printf("Résultat : %d, %c, %s\n", quantite, symbole, nom);

    return 0;
}

L'espace initiale dans " %c" permet de consommer les blancs résiduels. La fonction fflush(stdin) n'est pas portable pour vider l'entrée standard ; une boucle de lecture jusqu'au saut de ligne est préférable.

Spécificateurs de format pour printf

Un spécificateur de conversion a la forme :

%[flags][largeur][.précision][modificateur]type

Les crochets indiquent des parties optionnelles.

Indicateurs

Flag Effet
- Aligne le résultat à gauche dans le champ donné.
+ Fait précéder le nombre de son signe (+ ou -).
Insère un espace avant un nombre positif.
# Ajoute le préfixe 0, 0x ou 0X pour les formats octal/hexadécimal ; force l'affichage du point décimal pour f, e, E.
0 Remplit le champ avec des zéros au lieu d'espaces, à droite du signe.

Types principaux

Spécificateur Signification
d, i Entier signé en base 10.
u Entier non signé en base 10.
o Entier non signé en base 8.
x, X Entier non signé en base 16 (minuscules/majuscules).
f Nombre flottant en notasion décimale.
e, E Nombre flottant en notation exponentielle.
g, G Choisit la représentation la plus courte entre %f et %e.
c Un seul caractère.
s Chaîne de caractères terminée par '\0'.
p Adresse d'un pointeur.
lu unsigned long.
llu unsigned long long.

Précision

  • Entiers : nombre minimal de chiffres (complété par des zéros).
  • f, e, E : nombre de chiffres après le point.
  • g, G : nombre maximum de chiffres significatifs.
  • s : nombre maximum de caractères affichés.

Modificateurs de longueur

Modificateur Utilisation
h short ou unsigned short pour les entiers.
l long/unsigned long pour les entiers ; caractères larges pour c/s.
L long double pour les flottants.

Exemples d'affichage

int nb = 42;
double pi = 3.14159;
char mot[] = "exemple";

printf("Nombre :   [%10d]\n", nb);
printf("Gauche :   [%-10d]\n", nb);
printf("Zéros :    [%010d]\n", nb);
printf("Signé :    [%+d]\n", nb);
printf("Flottant : [%.2f]\n", pi);
printf("Hexa :     [0x%x]\n", nb);
printf("Chaîne :   [%.5s]\n", mot);

Étiquettes: C stdio scanf printf fgets

Publié le 17 juillet à 01h54