2 votes

Comment lire un fichier et valider l'entrée ?

Aujourd'hui, j'apprends à connaître les fichiers en C et j'ai trouvé un problème

J'ai d'abord créé un fichier texte comme ci-dessous :

5 1 5 2 4 -3 

Le premier élément est la taille du tableau et j'ai écrit une fonction pour lire toutes les valeurs positives dans un tableau d'entiers en utilisant ce code :

void readFileToArray(char *fname, int *a, int *pn) {
    int number;
    int quantity;
    FILE *fp = fopen(fname, "r");
    fscanf(fp, "%d", &quantity);
    while (*pn < quantity) {
        fscanf(fp, "%d", &number);
        if (number >= 0) {
            a[*pn] = number;
            (*pn)++;
        }
        else 
            quantity--;
    }
    fclose(fp);
}

Et il a réussi à lire 1 5 2 4 dans le tableau.

Ensuite, j'ai changé le fichier texte en ceci

5 1a 5 2 4 -3

Grâce à Tutorialspoint, j'ai trouvé comment éliminer 1a et lire 5, 2, 4 dans le tableau avec ce code

void readFileToArray(char *fname, int *a, int *pn) {
    int number, test;
    char space;
    int quantity;
    FILE *fp = fopen(fname, "r");
    fscanf(fp, "%d", &quantity);
    while (*pn < quantity) {
        fpurge(stdin);
        test = fscanf(fp, "%d%c", &number, &space);
        if (test != 2 || space != ' ')
            quantity--;
        else {
            a[*pn] = number;
            (*pn)++;
        }
    }   
    fclose(fp);
}

Cependant, avec le fichier texte

5 1a a5 2 4 -3

Le bloc de code précédent ne peut pas lire le fichier dans le tableau. Lorsque j'ai essayé de déboguer, j'ai remarqué la ligne de code suivante

test = fscanf(fp, "%d%c", &number, &space);

Il lit a5 et renvoie la valeur 0, ce qui est correct. En ce moment :

number = 1
space = a //because it cannot read a5 into the format %d%c

Cependant, lors de l'exécution de la boucle suivante, le nombre et l'espace conservaient les valeurs 1 et a jusqu'à la fin de la boucle. Sortie du programme sans valeur lue dans le tableau

Quelqu'un peut-il m'expliquer pourquoi et me proposer une solution ?

P/s : désolé pour mon mauvais anglais.

1voto

Dans votre code, l'appel de la fonction fscanf() recherche un motif dans le flux d'entrée (c'est-à-dire le texte de votre fichier), qui doit commencer par un nombre entier décimal. Comme "a5" ne commence pas par un nombre entier ou un signe ('-'), un échec de la correspondance se produit. Lorsque l'échec de la correspondance se produit, le caractère "a" est repoussé sur le flux, et la fonction fscanf revient. Pendant les boucles successives, la même chose se produit, puisque le flux d'entrée provient d'un fichier, et ne changera pas.

Un problème très similaire a été discuté dans le fil de discussion suivant sur le débordement de pile : Comportement de fscanf lorsque le format ne correspond pas au contenu du fichier

Puisque vous avez mentionné que vous apprenez le C, je vous suggère de regarder les différents exemples de code dans le livre "The C Programming Language by K&R". Je me souviens que certains de ces exemples utilisent getchar() pour analyser l'entrée de stdin. Vous pouvez utiliser les mêmes méthodes mais avec fgetc (comme mentionné précédemment par Sma). Je suis sûr que vous apprécierez la lecture du livre (et que vous apprendrez le langage en même temps !!).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X