c++ - good - ¿Podemos escribir un personaje EOF nosotros mismos?
ifstream en c++ (9)
Bueno, EOF
es solo un valor devuelto por la función definida en el stdio.h
cabecera C stdio.h
. En realidad, el sistema operativo lo devuelve a todas las funciones de lectura, por lo que depende del sistema. Cuando el SO llega al final del archivo, lo envía a la función, que en su valor de retorno se coloca con mayor frecuencia ( -1
), pero no siempre. Entonces, para resumir, EOF
no es un caracter, sino una constante devuelta por el sistema operativo. EDITAR: Bueno, necesitas saber más sobre el sistema de archivos, mira this.
Hola, a tu segunda pregunta:
una vez más, deberías verte mejor en los filesystems
. FAT es un buen ejemplo, ya que puede encontrar muchos artículos al respecto, y sus principios son muy similares a NTFS. De todos modos, una vez más, EOF NOT a character
es NOT a character
. No puedes colocarlo en el archivo directamente. Si puede hacerlo, imagine las consecuencias, incluso el archivo de imagen "tonto" no podría ser leído por el sistema.
¿Por qué? Becouse OS funciona como una estructura de capas muy compleja. Una de las capas es el controlador del sistema de archivos. Se asegura de que transfiera datos de todos los sistemas de archivos conocidos por el conductor. Proporciona un puente entre las aplicaciones y el sistema real de almacenamiento de archivos en la unidad de disco duro.
Para ser exactos, el sistema de archivos FAT usa la llamada tabla FAT: es una tabla ubicada cerca del inicio del espacio de direcciones del disco duro (o partición), y contiene un mapa de todos los clústeres (celdas de almacenamiento pequeñas). Bien, entonces ahora, cuando quiera guardar algún archivo en la unidad de disco duro, OS (controlador del sistema de archivos) examina la tabla FAT y busca el valor "0x0". Este valor "0x0" le dice al sistema operativo que el clúster cuya dirección se describe por la ubicación de ese valor en la tabla FAT es libre de escribir.
Entonces escribe en ella la primera parte del archivo. Luego, busca otro valor "0x0" en FAT, y si lo encuentra, escribe la segunda parte del archivo en el clúster al que apunta. Luego, cambia el valor del primer registro de la tabla FAT donde el archivo se ubica a la dirección física del siguiente en nuestro caso, la segunda parte del archivo.
Cuando su archivo está todo almacenado en HDD, ahora viene la parte final, escribe el valor EOF deseado, pero en la tabla FAT, no en la "parte de datos" de la HDD. Entonces, cuando el archivo se lea la próxima vez, sabe que este es el final, no busque más.
Entonces, ya ves, si deseas escribir manualmente el valor de EOF en el lugar al que no pertenece, tienes que escribir tu propio controlador que podría reescribir el registro de FAT, pero esto es prácticamente imposible de hacer. principiantes.
La mayoría de los lenguajes, como C ++, al escribir en un archivo, ponen un carácter EOF incluso si omitimos escribir enunciados como:
filestream.close
Sin embargo, de alguna manera, podemos poner el carácter EOF de acuerdo con nuestro requisito, en C ++, para una instancia. O cualquier otro método que podamos usar aparte de usar las funciones proporcionadas en C ++.
Si necesita solicitar más información, haga un comentario.
Gracias por adelantado.
EDITAR: Gracias por su apoyo, pero aquí hay una adición a esta pregunta:
¿Qué pasa si queremos engañar al sistema operativo y colocar un carácter EOF en un archivo y escribir algunos datos después del EOF para que una aplicación como Notepad.exe no pueda leer después de nuestro carácter EOF. He leído las respuestas a la pregunta relacionada con este tema y he llegado a saber que actualmente el sistema operativo no suele ver para un personaje EOF, sino que comprueba la longitud del archivo para tener la idea correcta de conocer la longitud del archivo, pero debe ser un procedimiento en el SO que verifique la longitud del archivo y luego actualice los registros del archivo.
Lamento si me equivoco en algún momento de mi estimación, pero, por favor, ayúdenme porque puede generar muchas ideas nuevas.
En Windows, si encuentra un ASCII 26 (EOF) en stdin, dejará de leer el resto de los datos. Creo que escribir este caracter también terminará la salida enviada a stdout, pero no lo he confirmado. Puede cambiar la transmisión al modo binario como en esta pregunta SO :
#include <io.h>
#include <fcntl.h>
...
_setmode(0, _O_BINARY)
Y no solo detendrá la conversión de 0x0A a 0x0D 0x0A, sino que también obtendrá la capacidad de leer / escribir 0x1A también. Tenga en cuenta que puede tener que cambiar tanto stdin (0) como stdout (1).
En los sistemas de archivos modernos, EOF no es un personaje, por lo que no tiene que emitirlo cuando termina de escribir en un archivo. Solo tiene que cerrar el archivo o dejar que el sistema operativo lo haga por usted cuando finalice su proceso.
En realidad, en C ++ no hay un carácter EOF físico escrito en un archivo utilizando los mecanismos fprintf () o ostream. EOF es una condición de E / S para indicar que no hay más datos para leer.
Algunos sistemas operativos de disco tempranos como CP / M en realidad usaban un 0x1A físico (carácter ASCII SUB) para indicar EOF porque el sistema de archivos solo mantenía el tamaño del archivo en bloques, por lo que nunca se sabía exactamente cuánto tiempo estaba un archivo en bytes. Con la llegada de almacenar recuentos de longitud reales en el directorio ya no es típico almacenar un carácter "EOF" como parte de los datos de archivos "en banda".
Nadie ha mencionado aún las [f]truncate
llamadas [f]truncate
sistema, que son cómo hace que un archivo sea más corto sin volver a crearlo desde cero.
Las funciones
truncate()
yftruncate()
hacen que el archivo normal nombrado porpath
o referenciado porfd
se trunque a un tamaño de bytes delength
precisa.Si el archivo anteriormente era más grande que este tamaño, los datos adicionales se pierden. Si el archivo anteriormente era más corto, se extiende y la parte extendida se lee como bytes nulos (
''/0''
).
Comprenda que esta es una operación distinta de escribir cualquier clase de datos en el archivo. El archivo es una matriz lineal de bytes, distribuida de alguna manera en el disco, con metadatos que dicen cuánto tiempo; truncate
cambia los metadatos.
No existe el personaje "EOF". El hecho de cerrar el flujo en sí mismo es la condición "EOF".
Cuando presiona Ctrl + D en un shell unix, eso simplemente cierra el flujo de entrada estándar, que a su vez es reconocido por el shell como "EOF" y se cierra.
Por lo tanto, para "enviar" un "EOF", simplemente cierre la secuencia a la que se debe enviar el "EOF".
No hay un caracter EOF EOF por definición "no es igual a ningún código de carácter válido". A menudo es -1. No está escrito en el archivo en ningún momento.
Existe un valor de carácter EOF histórico (CTRL + Z) en DOS, pero actualmente está obsoleto.
Para responder a la pregunta de seguimiento de Apoorv: El sistema operativo nunca usa los datos del archivo para determinar la longitud del archivo (los archivos no son "terminados en nulo" de ninguna manera). Entonces no puedes engañar al sistema operativo. Quizás los viejos y estúpidos programas no se leerán después del carácter CTRL + Z. No asumiría que cualquier aplicación de Windows (incluso Notepad) lo haría. Creo que sería más fácil engañarlos con un carácter nulo ( /0
).
Si por el carácter EOF te refieres a algo como Control-Z, entonces los sistemas operativos modernos no necesitan tal cosa, y el tiempo de ejecución C ++ no escribirá uno para ti. Por supuesto, puede escribir uno usted mismo:
filestream.put( 26 ); // write Ctrl-Z
pero no hay una buena razón para hacerlo. Tampoco hay necesidad de hacer:
filesystem.close();
ya que la secuencia de archivos se cerrará automáticamente cuando se invoque su destructor, pero es (creo) una buena práctica hacerlo.
Vine aquí mientras hacía los ejercicios de Kernighan & Ritchie C.
Ctrl + D envía el caracter que coincide con la constante EOF
de stdio.h
.
(Editar: esto está en Mac OS X; gracias a @markmnl por señalar que el equivalente de Windows 10 es Ctrl + Z )