2009-10-26 13 views
6

¿EOF siempre es negativo?¿EOF siempre es negativo?

Estoy pensando en escribir una función que lea la siguiente palabra en la entrada y devuelva el número de línea en el que se encontró la palabra o EOF si se ha alcanzado el final de la entrada. Si EOF no es necesariamente negativo, la función sería incorrecta.

+1

¿Por qué incluso necesita devolver EOF de su propia función? Simplemente defina su función como "devuelve el número de línea donde se encontró la palabra, o -1 si se llegó al final de la entrada". Dicho esto, muchas fuentes (por ejemplo, Código Completo) advierten contra la mezcla de valores devueltos con códigos de falla. –

+0

Correcto, es una alternativa posible y completamente viable. Sin embargo, pensé que EOF habría sido más explícito. – Ree

Respuesta

10

Sí, EOF siempre es negativo.

La norma dice:

7,19 de entrada/salida
7.19.1 Introducción

3 Las macros son [...] EOF que expande a un número entero constante expresión, con el tipo int y un valor negativo , que es devuelto por varias funciones para indicar de fin de archivo, es decir, no más de entrada de una corriente;

Tenga en cuenta que no hay ningún problema con la "simple" char firmada. Las funciones <stdio.h> que tratan con char s, específicamente emiten los caracteres a unsigned char y luego a int, de modo que todos los caracteres válidos tengan un valor positivo. Por ejemplo:

int fgetc(FILE *stream) 

7.19.7.1
... la función fgetc obtiene ese personaje como un unsigned char convertido a un int ...

+3

Existe un problema si 'sizeof (char) == sizeof (int)', aunque como el molde a través de 'unsigned char' no mantendrá necesariamente todos los valores' char' válidos como positivos. Afortunadamente esto es relativamente raro. –

+0

Eso es solo un problema si asume erróneamente que un valor negativo es siempre EOF ('if (ch <0)/* EOF detectado * /;') o si el "juego de caracteres de ejecución" usa todos los valores de 'INT_MIN' a' 0' en cuyo caso el valor 'EOF' es el mismo que el valor de un carácter válido. – pmg

15

EOF es siempre == EOF. No asumas nada más.

En una segunda lectura de la norma (y según algunos otros comentarios aquí) parece que EOF siempre es negativo, y para el uso especificado en esta pregunta (número de línea o EOF) funcionaría. Lo que pretendo prevenir (y aún lo hago) es suponer que los personajes son positivos y EOF es negativo.

Recuerde que es posible que una implementación C estándar conformes tenga valores de caracteres negativos; esto incluso se menciona en 'El lenguaje de programación C' (K & R). Los caracteres de impresión son siempre positivos, pero en algunas arquitecturas (probablemente todas antiguas), los caracteres de control son negativos. El estándar C no especifica si el tipo char está firmado o no, y la única constante de caracteres que garantiza tener el mismo valor en todas las plataformas es '\0'.

+0

¿Podría agregar algunas referencias? – Guillaume

+6

Esto no es correcto. El macro EOF ** debe ** expandirse a un entero negativo, desafortunadamente no tengo mi copia del estándar a mano en este momento. –

+0

La referencia de biblioteca C, que dice que toma casi toda su información del estándar ANSI C, dice que "EOF es un número entero negativo que indica que se ha alcanzado un final de archivo" (http: //www.acm .uiuc.edu/webmonkeys/book/c_guide/2.12.html # variables). Dicho esto, aún diría que es un mal estilo y, además de eso, es innecesario suponer que EOF es negativo. –

8

tener esa función de retorno

  • el número de línea de la palabra se encontró en
  • o -1 en caso de que se ha alcanzado
Problema

resolvió el final de la entrada, sin necesidad para confiar en cualquier valor de EOF. El que llama puede probar fácilmente si es mayor o igual a cero para una llamada exitosa, y asume que EOF/IO-error de lo contrario.

+0

De hecho, es una buena alternativa. – Ree

1

EOF es una condición, más que un valor. El valor exacto de este centinela es la implementación definida. En muchos casos, es un número negativo.

1

De wikipedia:

El valor real de EOF es un número negativo dependiente del sistema, comúnmente -1, que se garantiza que sea desigual a cualquier código de carácter válido.

Pero no hay referencias ...

De codificación segura: Detect and handle input and output errors EOF es negativo pero sólo cuando sizeof(int) > sizeof(char).

+0

Wikipedia no es completamente correcto aquí. EOF podría ser -1, y con los caracteres firmados un carácter puede tener un valor -1 (por ejemplo, el símbolo del euro en windows-1252). ¿Cuál es el caso es que el valor de retorno de '(f) getc' es el siguiente carácter lanzado a un char sin signo y luego a un' int' y esto no debería coincidir con 'EOF'.Por supuesto, esto solo puede funcionar si 'sizeof (int)! = Sizeof (char)'. –

2

Desde el online draft n1256, 17.9.1.3 :

EOF

que se expande a una expresión constante entera, con tipo int y un valor negativo, que devuelve varias funciones para indicar fin de archivo, es decir, no más entrada de una secuencia;

EOF siempre es negativo, aunque puede que no siempre sea -1.

Por cuestiones como ésta, prefiero separar las condiciones de error de datos, devolviendo un código de error (SUCCESS, END_OF_FILE, READ_ERROR, etc.) como valor de retorno de la función, y luego escribir los datos de interés para los parámetros separados, tales como

int getNextWord (FILE *stream, char *buffer, size_t bufferSize, int *lineNumber) 
{ 
    if (!fgets(buffer, bufferSize, stream)) 
    { 
    if (feof(stream)) return END_OF_FILE; else return READ_ERROR; 
    } 
    else 
    { 
    // figure out the line number 
    *lineNumber = ...; 
    } 
    return SUCCESS; 
}