2009-09-15 11 views
20

J'utilise le code C suivant pour prendre l'entrée de l'utilisateur jusqu'à ce que l'EOF se produise, mais le problème est que ce code ne fonctionne pas, il se termine après avoir pris la première entrée. Quelqu'un peut-il me dire ce qui ne va pas avec ce code. Merci d'avance.Détection EOF en C

float input; 

printf("Input No: "); 
scanf("%f", &input); 

while(!EOF) 
{ 
    printf("Output: %f", input); 
    printf("Input No: "); 
    scanf("%f", &input); 
} 
+3

Note: En supposant que l'entrée utilisateur n'est pas canalisé, la vérification de EOF est probablement pas idéal, car IIRC généralement cela signifie que l'utilisateur doit appuyer sur Ctrl + D pour arrêter de fumer, ce qui n'est pas évident – Brian

Répondre

40

EOF est juste une macro avec une valeur (généralement -1). Vous devez tester quelque chose contre EOF, comme le résultat d'un appel getchar().

Une façon de tester la fin d'un flux est avec la fonction feof.

if (feof(stdin)) 

Notez qu'après un échec de lecture de l'état « fin du flux » ne sera mis .

Dans votre exemple, vous devriez probablement vérifier la valeur de retour de scanf et si cela indique qu'aucun champ n'a été lu, vérifiez la fin du fichier.

+2

Merci Charles Bailey. – itsaboutcode

+3

Et notez le commentaire de Brian: stdin n'enregistre normalement pas EOF, car il y a toujours plus de choses que l'utilisateur peut taper. Sur un système Unixy, cela signifie généralement control-D. –

+0

Cela dépend de ce que vous voulez dire "normalement". Si vous avez redirigé stdin (fichier ou pipe, unix ou windows), EOF est généralement signalé correctement. Dans un terminal unix interactif^D fonctionne habituellement, en mode texte Windows,^Z au début d'une ligne fonctionne. –

8

EOF est une constante dans C. Vous ne vérifiez pas le fichier réel pour EOF. Vous devez faire quelque chose comme ça

while(!feof(stdin)) 

Voici la documentation à feof. Vous pouvez également vérifier la valeur de retour de scanf. Il renvoie le nombre d'éléments convertis avec succès, ou EOF s'il atteint la fin du fichier.

+0

la fonction FILE contient-elle une variable qui serait mieux testée que EOF? il semble juste qu'il serait préférable de vérifier un statut sur le pointeur de fichier réel, que d'utiliser une fonction étrange qui ne fonctionne que la moitié du temps. – MarcusJ

0

comme point de départ, vous pouvez essayer de remplacer

while(!EOF) 

avec

while(!feof(stdin)) 
4

Une autre question est que vous lisez avec scanf("%f", &input); seulement. Si l'utilisateur tape quelque chose qui ne peut pas être interprété comme un nombre à virgule flottante C, comme "pi", l'appel scanf() n'attribuera rien à input, et ne progressera pas à partir de là. Cela signifie qu'il tenterait de continuer à lire "pi" et d'échouer. Étant donné le changement à while(!feof(stdin)) que d'autres affiches recommandent correctement, si vous avez tapé "pi" il y aurait une boucle sans fin d'imprimer l'ancienne valeur de input et l'impression de l'invite, mais le programme ne traiterait jamais de nouveau contribution.

scanf() renvoie le nombre d'affectations aux variables d'entrée effectuées. S'il n'a fait aucune affectation, cela signifie qu'il n'a pas trouvé de nombre à virgule flottante, et vous devriez lire plus d'entrées avec quelque chose comme char string[100];scanf("%99s", string);. Cela supprimera la chaîne suivante du flux d'entrée (jusqu'à 99 caractères, de toute façon - le char supplémentaire est pour le terminateur null sur la chaîne).

Vous savez, cela me rappelle toutes les raisons que je déteste scanf(), et pourquoi j'utilise fgets() à la place, puis peut-être l'analyser en utilisant sscanf().

-1

Vous souhaitez vérifier le résultat de scanf() pour vous assurer que la conversion a abouti; s'il n'y avait pas, alors l'une des trois choses est vrai:

  1. scanf() s'étouffe un caractère non valide pour le% spécificateur de conversion f (c.-à quelque chose qui est pas un chiffre, point, 'e' ou 'E');
  2. scanf() a détecté EOF;
  3. scanf() a détecté une erreur lors de la lecture de stdin.

Exemple:

int moreData = 1; 
... 
printf("Input no: "); 
fflush(stdout); 
/** 
* Loop while moreData is true 
*/ 
while (moreData) 
{ 
    errno = 0; 
    int itemsRead = scanf("%f", &input); 
    if (itemsRead == 1) 
    { 
    printf("Output: %f\n", input); 
    printf("Input no: "); 
    fflush(stdout); 
    } 
    else 
    { 
    if (feof(stdin)) 
    { 
     printf("Hit EOF on stdin; exiting\n"); 
     moreData = 0; 
    } 
    else if (ferror(stdin)) 
    { 
     /** 
     * I *think* scanf() sets errno; if not, replace 
     * the line below with a regular printf() and 
     * a generic "read error" message. 
     */ 
     perror("error during read"); 
     moreData = 0; 
    } 
    else 
    { 
     printf("Bad character stuck in input stream; clearing to end of line\n"); 
     while (getchar() != '\n') 
     ; /* empty loop */ 
     printf("Input no: "); 
     fflush(stdout); 
    } 
} 
+1

boucle infinie possible lors du passage à la fin de la ligne. Je suggère '' while (((ch = getchar())! = EOF) && (ch! = '\ N'))/* void * /; '' annonce puis vérifie (à nouveau) pour EOF et paramètre '' moredata = 0; '' – pmg

+0

Veuillez ouvrir une nouvelle question. – andig

-2
while(scanf("%d %d",a,b)!=EOF) 
{ 

//do ..... 
} 
+0

j'ai fait en utilisant ce .... –

+0

quoi de mal:/je ne comprends pas –

Questions connexes