¿Es EOF siempre negativo?

¿Es EOF siempre 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 que se encontró la palabra o EOF si se ha llegado al final de la entrada. Si EOF no es necesariamente negativo, la función sería incorrecta.

Sí, EOF siempre es negativo.

El estándar dice:

7.19 Entrada / salida
7.19.1 Introducción

3 Las macros son […] EOF que se expanden a una expresión constante de tipo entero, con tipo int y un valor negativo, que son devueltas por varias funciones para indicar el final del archivo, es decir, no más entrada de un flujo;

Tenga en cuenta que no hay ningún problema con la firma “simple” de caracteres. Las funciones que tratan con caracteres, específicamente convierten los caracteres en caracteres unsigned char y luego en 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 carácter como un personaje sin signo convertido a int …

EOF es siempre == EOF . No asums 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 pretendía advertir (y aún lo hago) es asumir que los personajes son positivos y EOF es negativo.

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

Tener esa función de vuelta

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

Problema resuelto, sin necesidad de confiar en ningún valor de EOF. La persona que llama puede probar fácilmente una llamada exitosa mayor o igual a cero, y asumir EOF / IO-error de lo contrario.

Del borrador en línea n1256 , 17.9.1.3:

EOF

que se expande a una expresión constante de tipo entero, con el tipo int y un valor negativo, que son devueltas por varias funciones para indicar el final del archivo , es decir, no más entradas de un flujo;

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

Para problemas como este, prefiero separar las condiciones de error de los datos devolviendo un código de error ( SUCCESS , END_OF_FILE , READ_ERROR , etc.) como valor de retorno de la función, y luego escribiendo los datos de interés en parámetros separados, 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; } 

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

De wikipedia :

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

Pero no hay referencias …

De la encoding segura: Detecte y maneje los errores de entrada y salida. EOF es negativo, pero solo cuando sizeof (int)> sizeof (char) .