HOWTO · C

Lire le fichier ligne par ligne en utilisant fscanf en C

Cet article montre comment lire un fichier ligne par ligne en utilisant le fscanf en C

Sur cette page

fscanf lit des données formatées depuis un flux FILE. Un scanset peut récupérer des caractères jusqu’à une nouvelle ligne, mais, contrairement à une fonction dédiée à la lecture de lignes, il faut gérer explicitement les lignes vides et les blocs de taille limitée. Pour les fichiers texte ordinaires, fgets est généralement plus simple ; utilisez fscanf lorsque le format d’entrée nécessite des conversions.

Lire un fichier ligne par ligne avec fscanf en C

Cet exemple complet crée un fichier temporaire, y écrit deux lignes d’exemple, puis lit le flux avec un scanset limité au tampon de destination de 16 octets. Le programme affiche les deux lignes à mesure qu’il les lit. Les chaînes visibles dans l’exemple restent en anglais.

#include <stdio.h>

int main(void) {
    FILE *file = tmpfile();
    char line[16];

    if (file == NULL) {
        return 1;
    }
    if (fputs("First line.\nSecond line.\n", file) == EOF || ferror(file)) {
        fclose(file);
        return 1;
    }
    if (fflush(file) == EOF || ferror(file)) {
        fclose(file);
        return 1;
    }
    rewind(file);

    for (;;) {
        int result = fscanf(file, "%15[^\n]", line);
        if (result == 1) {
            int ch;
            puts(line);
            ch = fgetc(file);
            if (ch == '\n') {
                continue;
            }
            if (ch == EOF) {
                break;
            }
            ungetc(ch, file);
            while ((ch = fgetc(file)) != '\n' && ch != EOF) {
            }
            if (ch == EOF) {
                break;
            }
            continue;
        }
        if (result == EOF) {
            break;
        }
        if (fgetc(file) == '\n') {
            puts("");
        }
    }

    fclose(file);
    return 0;
}

Une largeur de 15 laisse la place au caractère nul de fin dans line. Après chaque conversion réussie du scanset, le programme vérifie la présence d’une nouvelle ligne. Si une ligne dépasse la capacité du tampon, il en élimine le reste avant de lire la suivante ; la mémoire utilisée reste ainsi limitée, mais la ligne longue n’est pas conservée dans son intégralité. Si le scanset ne trouve aucun caractère avant une nouvelle ligne, la boucle consomme celle-ci et affiche une ligne vide au lieu de réessayer sans avancer. En production, vérifiez également ferror(file) après la fin de la lecture afin de distinguer une erreur de lecture de la fin normale du fichier.

Lire des jetons séparés par des espaces avec fscanf

Pour analyser des jetons, %255s lit un jeton non blanc dans un tampon char token[256]. La largeur empêche d’écrire au-delà du tableau ; %s ignore les espaces blancs initiaux et s’arrête au prochain caractère blanc. La boucle ne doit continuer que tant que fscanf(file, "%255s", token) == 1 ; tester uniquement EOF peut entraîner une répétition sans fin si une conversion échoue sans consommer de données. Cette méthode traite volontairement les espaces, les tabulations et les nouvelles lignes comme des séparateurs : elle ne conserve donc pas les limites des lignes d’origine. Pour les champs numériques, utilisez les spécificateurs de conversion correspondants et vérifiez le nombre d’affectations réussies.

Utiliser fgets pour lire des lignes de manière fiable

Pour un texte où chaque enregistrement occupe une ligne, fgets(buffer, sizeof buffer, file) est généralement plus simple à raisonner. La fonction lit au maximum un caractère de moins que la capacité du tampon et conserve la nouvelle ligne si elle tient dans celui-ci. Vérifiez sa valeur de retour avant d’utiliser le tampon. Si le tampon se remplit sans contenir de nouvelle ligne, la ligne logique continue dans le flux ; lisez d’autres blocs ou éliminez le reste, selon la tâche. La dernière ligne peut se terminer à la fin du fichier sans nouvelle ligne. fgets gère aussi naturellement les lignes vides : elle peut renvoyer un tampon qui ne contient que le caractère de nouvelle ligne.

Choisissez fscanf pour lire des champs formatés ou des jetons séparés par des espaces. Choisissez fgets lorsque les limites des lignes doivent être conservées, puis analysez séparément la chaîne obtenue si nécessaire. Vérifiez toujours que fopen a réussi, contrôlez les résultats des conversions et fermez les flux après utilisation.