Détection de L'EOF en C

J'utilise le code C suivant pour prendre l'entrée de l'utilisateur jusqu'à ce que 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 à l'avance.

float input;

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

while(!EOF)
{
    printf("Output: %f", input);
    printf("Input No: ");
    scanf("%f", &input);
}
22
demandé sur Jens 2009-09-15 22:31:08

6 réponses

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 que l'État' fin du flux ' ne sera défini que après une lecture ayant échoué.

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.

40
répondu CB Bailey 2013-06-12 15:06:26

EOF est une constante en 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 de 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.

8
répondu A. Levy 2009-09-15 18:34:06

Un autre problème 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'affectera rien à input et ne progressera pas à partir de là. Cela signifie qu'il tenterait de continuer à lire "pi", et à échouer.

Étant donné le changement à while(!feof(stdin)) que les autres affiches recommandent correctement, si vous tapez "pi", il y aurait une boucle sans fin d'impression de l'ancienne valeur de input et d'impression l'invite, mais le programme ne traiterait jamais de nouvelles entrées.

scanf() renvoie le nombre d'affectations aux variables d'entrée effectuées. S'il n'a pas fait d'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 pour lesquelles je hate scanf(), et pourquoi j'utilise fgets() à la place, puis peut-être l'analyser en utilisant sscanf().

4
répondu David Thornley 2009-09-15 19:21:21

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

while(!EOF)

Avec

while(!feof(stdin))
-1
répondu Craig 2009-09-15 18:36:45

Vous voulez vérifier le résultat de scanf() pour vous assurer qu'il y a eu une conversion réussie; s'il n'y en avait pas, alors l'une des trois choses est vraie:

  1. scanf() s'étouffe sur un caractère qui n'est pas valide pour le spécificateur de conversion %f (c'est-à-dire, quelque chose qui n'est pas un chiffre, un point, un ' e 'ou un '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
répondu John Bode 2009-09-15 19:31:34
while(scanf("%d %d",a,b)!=EOF)
{

//do .....
}
-2
répondu Ankush Virmani 2015-08-01 13:04:02