2009-09-15 17 views
20

Estoy usando el siguiente código C para tomar la entrada del usuario hasta que se produzca EOF, pero el problema es que este código no funciona, sino que termina después de tomar la primera entrada. ¿Alguien puede decirme qué está mal con este código? Gracias por adelantado.Detectando EOF en C

float input; 

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

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

Nota: Suponiendo que la entrada del usuario no se canaliza, la comprobación de EOF probablemente no es ideal, ya IIRC generalmente que significa que el usuario debe golpear CTRL + D para dejar de fumar, que no es obvio – Brian

Respuesta

40

EOF es sólo una macro con un valor (usualmente -1). Tienes que probar algo en contra de EOF, como el resultado de una llamada getchar().

Una forma de probar el final de una secuencia es con la función feof.

if (feof(stdin)) 

Tenga en cuenta, que el 'fin de la corriente' estado sólo se establece después de una funcionado Leer más.

En su ejemplo, probablemente debería verificar el valor de retorno de scanf y si esto indica que no se leyeron campos, entonces verifique que el archivo esté en el final.

+2

Gracias Charles Bailey. – itsaboutcode

+3

Y tenga en cuenta el comentario de Brian: stdin normalmente no registra EOF, ya que siempre hay más que el usuario puede escribir. En un sistema Unixy, eso generalmente significa control-D. –

+0

Depende de lo que quieras decir mi 'normalmente'. Si ha redirigido stdin (archivo o conducto, Unix o Windows), EOF generalmente se señala correctamente. En un terminal Unix interactivo, por lo general, D funciona; en el modo de texto de Windows,^Z al comienzo de una línea funciona. –

8

EOF es una constante en C. No está revisando el archivo real de EOF. Que tiene que hacer algo como esto

while(!feof(stdin)) 

Aquí está la documentación para feof. También puede verificar el valor de retorno de scanf. Devuelve el número de elementos convertidos con éxito, o EOF si llega al final del archivo.

+0

¿La función ARCHIVO contiene una variable que sería mejor probar que usar EOF? simplemente parece que sería mejor verificar un estado en el puntero del archivo real, que usar alguna función extraña que solo funciona la mitad del tiempo. – MarcusJ

0

como punto de partida podría intentar reemplazar

while(!EOF) 

con

while(!feof(stdin)) 
4

Otra cuestión es que usted está leyendo, con sólo scanf("%f", &input);. Si el usuario escribe algo que no se puede interpretar como un número de coma flotante C, como "pi", la llamada scanf() no asignará nada al input, y no progresará desde allí. Esto significa que intentaría seguir leyendo "pi" y fallando.

Dado que los otros carteles son recomendables, si escribe "pi" habrá un bucle sin fin de impresión del valor anterior de input e imprimiendo el mensaje, pero el programa nunca procesará ningún nuevo entrada.

scanf() devuelve el número de asignaciones a las variables de entrada que realizó. Si no hizo ninguna asignación, eso significa que no encontró un número de coma flotante, y debería leer más entradas con algo como char string[100];scanf("%99s", string);. Esto eliminará la siguiente cadena de la secuencia de entrada (hasta 99 caracteres, de todos modos, el char adicional es para el terminador nulo en la cadena).

Sabes, esto me está recordando todas las razones que odio scanf(), y por eso uso fgets() lugar y luego tal vez analizarlo usando sscanf().

-1

Quiere verificar el resultado de scanf() para asegurarse de que hubo una conversión exitosa; si no había, entonces una de las tres cosas es cierta:

  1. scanf() se asfixia con un carácter que no es válido para el indicador de conversión f% (es decir, algo que no es un dígito, punto, 'e' o 'E');
  2. scanf() ha detectado EOF;
  3. scanf() ha detectado un error al leer stdin.

Ejemplo:

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

posible bucle infinito al borrar al final de la línea. Sugiero '' while (((ch = getchar())! = EOF) && (ch! = '\ N'))/* void * /; 'ad, luego verificando (nuevamente) para EOF y configurando' 'moredata = 0; '' – pmg

+0

Por favor, abra una nueva pregunta. – andig

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

//do ..... 
} 
+0

lo he hecho usando esto .... –

+0

qué pasa:/no entiendo –