¿Cuál es el último personaje en un archivo?


19

Acabo de leer las respuestas a "Eliminar un carácter de nueva línea al final de un archivo" y todos dijeron que eliminaran el último carácter. Mi pregunta es, ¿no es el personaje eof el último?



1
@SorenBjornstad También me gustaría agregar que cuando hay una nueva línea al final de un archivo de texto de Unix, está ahí porque termina la última línea. Un archivo de texto vacío no tiene línea nueva al final: es una secuencia de cero caracteres.
Kaz

3
Para ser un poco pedante, CPM y DOS usaron ^ Z como el carácter EOF, y aún puede encontrar archivos que terminan con ^ Z.
Edward Falk

Respuestas:


13

Un archivo no termina con un carácter de Fin de archivo, ya que las respuestas anteriores indican correctamente. Pero creo que las respuestas y comentarios contienen algunas imprecisiones que vale la pena señalar:

  • El juego de caracteres ASCII no contiene un carácter EOF exacto. Hay varios caracteres de control de "fin": Fin del texto (3), Fin de la transmisión (4), Fin del bloque de transmisión (23), Fin del medio (25). El separador de archivos (28) puede acercarse más a un personaje EOF El código 26 es "Sustituto", no EOF.

  • Ctrl- Dsolo está asociado con la entrada del terminal. Por ejemplo, el comando cat filea fileb filec > outfileno implica Ctrl- D. Por cierto, se puede cambiar el carácter EOF terminal para algo más que Ctrl- Dmediante el sttycomando.

  • Estrictamente hablando, Ctrl- D(o lo que sea que hayas cambiado) no es un código clave EOF. Lo que hace es hacer que la readllamada del sistema regrese con la entrada disponible, al igual que presionar la tecla de retorno hace que la llamada del sistema de lectura devuelva una línea de caracteres a la persona que llama. Por convención, un valor de retorno de cero de la llamada al sistema de lectura (es decir, lectura de cero caracteres) señala una condición de fin de archivo. Sin embargo, el archivo de entrada no se cierra automáticamente y, si la entrada proviene del terminal, no se coloca en el estado "fin de archivo". Puede escribir un programa que continúe leyendo desde el terminal incluso después de un "fin de archivo" y la llamada de lectura puede devolver un valor distinto de cero para la siguiente línea de entrada.

  • La analogía entre los personajes y eof EOL se puede ver si Ctrl- Dse pulsa cuando alguna entrada ya se ha escrito en la línea. Por ejemplo, si escribe "abc" y presiona Ctrl: Dla llamada de lectura regresa, esta vez con un valor de retorno de 3 y con "abc" almacenado en el búfer pasado como argumento. Dado que la lectura no devuelve 0, la convención anterior no interpreta esto como una condición EOF. De manera similar, al presionar regresar a hace que la llamada de lectura regrese con toda la línea de entrada (incluida la nueva línea). Puede probar esto con el catcomando: escriba algunos caracteres en la línea y presione Ctrl- D. Verá que los caracteres le devuelven el eco y catesperan más información.

  • Todo lo anterior solo se aplica cuando el terminal está en modo "cocido", en oposición al modo "sin procesar", en el cual el procesamiento de entrada de línea se minimiza. En modo sin procesar, un carácter Ctrl-D realmente se entrega al búfer de entrada.


19

Los caracteres de control ASCII tienen definiciones de la década de 1960 (en realidad, preceden a lo que podría considerarse una red ). No todos esos caracteres de control se utilizan de la manera en que se definieron para equipos de telecomunicaciones en ese entonces.

En sistemas tipo Unix, no hay necesidad de un EOFpersonaje; ninguno es usado. El sistema puede decirle a las aplicaciones cuántos bytes hay en un archivo:

  • En algunos otros sistemas (vistos en VMS, DOS, Windows), un control-Z puede actuar como un marcador de fin de archivo porque en versiones anteriores el sistema no podía decirle a algunas aplicaciones cuántos bytes hay en el archivo.

    En el caso de VMS, la limitación se debió a la forma en que funcionaba el tiempo de ejecución de C. Las aplicaciones en lenguaje ensamblador podrían (y obtuvieron) el tamaño de archivo correcto.

  • Los sistemas Unix en el shell usan convencionalmente control-D para decirle a una aplicación que se ha alcanzado un final de entrada (archivo), pero el control-D no se almacena en el archivo.

En C, EOFse hace -1a propósito para indicar que no es un carácter válido. La E / S estándar regresa EOFcuando se detecta una condición de fin de archivo, no un carácter especial.

Por cierto, los archivos no necesitan terminar con un carácter de nueva línea (avance de línea ASCII). Los editores de texto pueden hacer frente a archivos que son todos texto imprimible pero carecen de una nueva línea final.


8
POSIX define un archivo de texto como un archivo que contiene una secuencia de líneas y, a su vez, cada línea como una secuencia de caracteres que no son de nueva línea seguidos de una nueva línea. Por lo tanto, un archivo que termina con cualquier cosa que no sea 0x0A no es un archivo de texto conforme.
Damian Yerrick

2
Soy consciente de eso, por eso señalé que los editores de texto funcionan. (Los archivos binarios no tienen esa restricción).
Thomas Dickey

Realmente vale la pena señalar que los archivos destinados a ser manejados como texto que no tienen una nueva línea final siguen siendo posiblemente una mala forma (incluso si los editores de texto típicos se han codificado para compensar dichos archivos), al menos si realmente desea que sea ampliamente amigable / compatible, porque la falta de una nueva línea final puede agregar dificultades adicionales en varias circunstancias (concatenación / impresión de múltiples archivos de texto, análisis con herramientas típicas de línea de comandos, editores mínimos como busybox's vi, etc.).
mtraceur

(1) Antes de VMS, RT-11 RSX-11 TOPS-10 tenía sistemas de archivos solo precisos para un bloque y necesitaba un carácter EOF. También lo hizo CP / M, que aparentemente lo copió de DEC y, a su vez, lo copió MS-DOS temprano y luego lo pasó a Windows. (2) En Unix es el controlador tty, no el shell, como lo describe JohanM con más detalle, aunque las personas suelen ejecutar shells en dispositivos tty.
dave_thompson_085

Claro, DEC estaba allí (y tenga en cuenta que mencioné versiones anteriores ). Si fue el origen de la función CP / M sería un tema interesante para explorar (no aquí); Mencioné esos casos para dar algunos antecedentes a las alternativas.
Thomas Dickey

7

EOF no es un personaje. Es un estado que indica que no hay más caracteres para leer de una secuencia de archivos. Cuando ingresa el comando EOF desde el terminal, está indicando al sistema operativo que cierre la secuencia de entrada, sin poner un carácter especial.


1
Sí, pero en la tabla ASCII EOF es 26, así que pensé que el último byte era la representación binaria de 26. Entonces, ¿cómo podría un programa que lee una entrada saber dónde termina?
sworwitz

ASCII estaba destinado a pasar información a través de una red. En ese caso, necesitas un personaje EOF. (ASCII también tenía muchos códigos de control. No todo era imprimible). En el caso de las secuencias de archivos, el tamaño del archivo ya se conoce a través del sistema de archivos para que el sistema operativo pueda saber cuándo no hay más datos para leer.
Munir

@sworwitz: Con respecto a C, las funciones de lectura de entrada que devuelven un carácter por llamada devuelven un int (generalmente un número de 32 bits, pero debe tener un mínimo de 16 bits), no un carácter. La función señala y EOF devolviendo -1 (0xffffffff), que no es un valor válido de 8 bits, por lo que no se confundirá con ningún carácter ASCII, ni siquiera 0xff. Las funciones que devuelven una cadena también devuelven la longitud de los datos leídos. Esta longitud se puede usar para indicar que no hay datos o el final de los datos (nuevamente, la longitud puede ser -1). Finalmente, también hay una función a la que puede llamar que le dirá si una transmisión ha llegado al final
slebetman

¡Ok, gracias! Entonces, cuando en bash presiono Ctrl + d, ingreso el carácter ASCII, ¿verdad?
sworwitz

@sworwitz No exactamente. Antes de bashponer las manos en la entrada, el controlador TTY lo masajea. Este controlador intercepta Ctrl-D y envía un EOF a bash (donde EOF no es un personaje, sino un estado de archivo especial)
Stig Hemmer
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.