Quiero volver a abrir los manejadores de archivos stdin y stdout (y tal vez stderr mientras estoy en él), de modo que futuras llamadas a printf () o putchar () o puts () irán a un archivo y futuras llamadas a getc () Vendrá de un archivo. 1) No quiero perder permanentemente entrada / salida / error estándar. Es posible que desee reutilizarlos más tarde en el programa. 2) No quiero abrir nuevos manejadores de archivos porque estos manejadores de archivos tendrían que ser pasados alrededor de un montón o global (temblar). 3) No quiero usar ningún open () o fork () u otras funciones dependientes del sistema si no puedo ayudarlo. Así que, básicamente, ¿funciona para hacer esto: Y, si lo hace, ¿cómo puedo obtener el valor original de stdin de nuevo ¿Tengo que guardarlo en un archivo y acaba de volver más tarde ¿Por qué utilizar freopen (). La especificación C89 tiene la respuesta en una de las notas finales de la sección sobre ltstdio. hgt: 116. El uso principal de la función freopen es cambiar el archivo asociado con un flujo de texto estándar (stderr. Stdin o stdout), como aquellos No es necesario que los identificadores sean valores modificables a los que se pueda asignar el valor devuelto por la función fopen. Freopen se utiliza comúnmente, p. Stdin freopen (newin, r, stdin). Esto no es más portátil que fclose (stdin) stdin fopen (newin, r). Ambas expresiones intentan asignar a stdin. Que no está garantizado para ser asignable. La forma correcta de usar freopen es omitir la asignación: freopen (newin, r, stdin) Aclaración: Asignación sintáctica a stdin. Como en stdin fopen (.) O stdin freopen (.). No es portátil, porque stdin se permite ser una macro. Stdio. h puede contener define stdin builtingetstdin (). Y por supuesto usted no puede poner eso en el LHS de una asignación. ChrisLutz, la forma correcta de usar freopen es simplemente si (freopen (quotnewinquot, quotrquot, stdin) NULL). --- el valor de retorno es útil para indicar si la apertura falló, pero no debería generalmente asignarla a nada. Ndash Quuxplusone Dic 19 13 at 18:06 La función os dup2 () debe proporcionar lo que necesita (si no las referencias a lo que necesita). Más específicamente, puede dup2 () el descriptor de archivo stdin a otro descriptor de archivo, hacer otras cosas con stdin, y luego copiarlo de nuevo cuando lo desee. La función dup () duplica un descriptor de archivo abierto. Específicamente, proporciona una interfaz alternativa al servicio proporcionado por la función fcntl () usando el valor de comando constante FDUPFD, con 0 para su tercer argumento. El descriptor de archivo duplicado comparte cualquier bloqueo con el original. En el éxito, dup () devuelve un nuevo descriptor de archivo que tiene lo siguiente en común con el original: El mismo archivo abierto (o pipe) El mismo puntero de archivo (ambos descriptores de archivo comparten un puntero de archivo) El mismo modo de acceso (leer, escribir o leer) / Write) respondió Feb 25 09 at 6:22 La pregunta dice explícitamente no utilizar funciones dependientes del sistema, sin embargo. Ndash desenrollar Feb 25 09 at 6:55 Y la pregunta dice explícitamente limitar la de los arroyos abiertos / descriptores de archivos ndash Tim Post 9830 Feb 25 09 at 15:23 Esta es una versión modificada del método de Tim Post que usé / dev / tty en vez de / Dev / stdout. No sé por qué no funciona con stdout (que es un enlace a / proc / self / fd / 1): Al usar / dev / tty, la salida se redirige al terminal desde donde se lanzó la aplicación. Espero que esta información sea útil. Esto hace que la punta de la aguja en mi ronda-peg-cuadrado-agujero-o-metro, lo que está tratando de lograr Recuerde que stdin, stdout y stderr son descriptores de archivo 0, 1 y 2 para cada proceso recién creado. Freopen () debe mantener los mismos fds, solo les asigna nuevos flujos. Por lo tanto, una buena manera de asegurarse de que esto realmente está haciendo lo que quieres que haga sería: Creo que este es el comportamiento esperado de freopen (), como se puede ver, todavía está usando sólo tres descriptores de archivos (y arroyos asociados) . Esto anularía cualquier redirección de shell, ya que no habría nada para que el shell se redireccione. Sin embargo, es probable que va a romper las tuberías. Es posible que desee asegurarse de configurar un controlador para SIGPIPE, en caso de que su programa se encuentra en el extremo de bloqueo de un tubo (no FIFO, tubería). Asi que. / Yourprogram --stdout /tmp/stdout. txt --stderr /tmp/stderr. txt se debe realizar fácilmente con freopen () y mantener los mismos descriptores de archivos reales. Lo que no entiendo es por qué youd necesidad de ponerlos de nuevo una vez que cambia seguramente, si alguien pasó cualquiera de las opciones, que quieren que persista hasta que el programa terminado respondió Feb 25 09 at 15:31 Hi Tim. Tuve problemas con la entrada de comentarios en mi último mensaje. No tiene gusto de copy39n39paste por alguna razón. Quería ir a la lista de la salida y dar detalles de sys, pero se envió antes de que yo estaba listo. Las dos primeras instrucciones hacen como uno esperaría, sin embargo, la final y esto debería ir a la pantalla otra vez. I39m compilación en XCode clang 500.2.79 en Mac OS X 10.9.5. Incluso intenté reabrir stdout en / dev / tty también sin alegría. Es como si una vez que el stdout se ha redefinido, termina el juego. Ndash VectorVictor 29 de mayo a las 12:55 freopen resuelve la parte fácil. Mantener stdin viejo alrededor no es difícil si no ha leído nada y si está dispuesto a utilizar las llamadas al sistema POSIX como dup o dup2. Si youre comenzado a leer de él, todas las apuestas son apagado. Tal vez usted puede decirnos el contexto en el que este problema ocurre Id animarle a pegarse a las situaciones donde youre dispuesto a abandonar stdin antiguo y stdout y por lo tanto puede utilizar freopen. fopen (3) - Linux man página fopen, fdopen, freopen - flujo abierto Funciones Función Prueba Requisitos de macros para glibc (ver featuretestmacros (7)): fdopen (): POSIXCSOURCE gt 1 XOPENSOURCE POSIXSOURCE Descripción La función fopen () abre el archivo cuyo nombre es la cadena apuntada por path y asocia una secuencia con ella. El modo de argumento apunta a una cadena que comienza con una de las siguientes secuencias (posiblemente seguida de caracteres adicionales, como se describe a continuación): r Abra el archivo de texto para su lectura. El flujo se coloca al principio del archivo. Abierto para leer y escribir. El flujo se coloca al principio del archivo. Truncar el archivo a longitud cero o crear un archivo de texto para escribir. El flujo se coloca al principio del archivo. Abierto para leer y escribir. El archivo se crea si no existe, de lo contrario se trunca. El flujo se coloca al principio del archivo. Abrir para añadir (escribir al final del archivo). El archivo se crea si no existe. El flujo se coloca al final del archivo. Abrir para leer y agregar (escribir al final del archivo). El archivo se crea si no existe. La posición inicial del archivo para la lectura está al principio del archivo, pero la salida siempre se anexa al final del archivo. La cadena de modo también puede incluir la letra b como último carácter o como un carácter entre los caracteres de cualquiera de las cadenas de dos caracteres descritas anteriormente. Esto es estrictamente para la compatibilidad con C89 y no tiene ningún efecto el b se ignora en todos los sistemas conformes POSIX, incluyendo Linux. (Otros sistemas pueden tratar archivos de texto y archivos binarios de forma diferente y agregar la b puede ser una buena idea si hace E / S a un archivo binario y espera que su programa pueda ser portado a entornos no UNIX). Detalles de las extensiones glibc para el modo. Cualquier archivo creado tendrá el modo SIRUSR SIWUSR SIRGRP SIWGRP SIROTH SIWOTH (0666), modificado por el valor umask de los procesos (ver umask (2)). Las lecturas y escrituras pueden mezclarse en los flujos de lectura / escritura en cualquier orden. Tenga en cuenta que ANSI C requiere que una función de posicionamiento de archivos intervenga entre la salida y la entrada, a menos que una operación de entrada se encuentre al final del archivo. (Si esta condición no se cumple, entonces se le permite a una lectura devolver el resultado de escrituras que no sean las más recientes.) Por lo tanto, es una buena práctica (ya veces incluso necesaria bajo Linux) poner un fseek (3) o fgetpos (3 ) Operación entre escritura y operaciones de lectura en tal flujo. Esta operación puede ser una aparente no-op (como en fseek (.0L, SEEKCUR) llamado para su efecto secundario de sincronización. Abrir un archivo en el modo de anexar (a como el primer carácter de modo) hace que todas las operaciones de escritura posteriores a este flujo a La función fdopen () asocia una secuencia con el descriptor de archivo existente, fd. El modo de la secuencia (uno de los valores r, r, w, w, a, A) debe ser compatible con el modo del descriptor de archivo El indicador de posición de archivo de la nueva secuencia se fija en la que pertenece a fd y los indicadores de error y de final de archivo se borran Los modos w o w no causan truncamiento Del archivo El descriptor de archivo no se engaña y se cerrará cuando se cierre el flujo creado por fdopen () El resultado de aplicar fdopen () a un objeto de memoria compartida no está definido La función freopen () abre el archivo cuyo Name es la cadena apuntada por path y asocia la secuencia apuntada por stream con ella. La secuencia original (si existe) se cierra. El argumento mode se utiliza como en la función fopen (). El uso principal de la función freopen () es cambiar el archivo asociado con un flujo de texto estándar (stderr. Stdin o stdout). Valor de retorno Al finalizar con éxito fopen (), fdopen () y freopen () devuelven un puntero FILE. De lo contrario, se devuelve NULL y errno se establece para indicar el error. Errores El modo proporcionado a fopen (), fdopen () o freopen () no es válido. Las funciones fopen (), fdopen () y freopen () también pueden fallar y establecer errno para cualquiera de los errores especificados para la rutina malloc (3). La función fopen () también puede fallar y establecer errno para cualquiera de los errores especificados para la rutina abierta (2). La función fdopen () también puede fallar y establecer errno para cualquiera de los errores especificados para la rutina fcntl (2). La función freopen () también puede fallar y establecer errno para cualquiera de los errores especificados para las rutinas open (2), fclose (3) y fflush (3). Conforming To Las funciones fopen () y freopen () se ajustan a C89. La función fdopen () cumple con POSIX.1-1990. Notas Notas de Glibc La biblioteca de GNU C permite las siguientes extensiones para la cadena especificada en modo. C (desde glibc 2.3.3) No realice la operación de apertura, o subsecuentes operaciones de lectura y escritura, los puntos de cancelación de hilo. Este indicador se ignora para fdopen (). E (desde glibc 2.7) Abra el archivo con el indicador OCLOEXEC. Consulte open (2) para obtener más información. Este indicador se ignora para fdopen (). M (desde glibc 2.3) Intenta acceder al archivo usando mmap (2), en lugar de llamadas al sistema de E / S (read (2), write (2)). En la actualidad, el uso de mmap (2) sólo se intenta para un archivo abierto para la lectura. X Abra el archivo exclusivamente (como el indicador OEXCL de open (2)). Si el archivo ya existe, fopen () falla y establece errno en EEXIST. Este indicador se ignora para fdopen (). Además de los caracteres anteriores, fopen () y freopen () soportan la siguiente sintaxis en modo. La cadena dada se toma como el nombre de un conjunto de caracteres codificados y el flujo se marca como ancho-orientado. A partir de entonces, las funciones de conversión interna convierten E / S en y desde la serie de caracteres. Si no se especifica la sintaxis de cadenas ccs, la orientación amplia del flujo se determina mediante la primera operación de archivo. Si esa operación es una operación de carácter ancho, el flujo se marca con una orientación amplia y se cargan las funciones para convertirlas al conjunto de caracteres codificado. Bugs Cuando se analiza para caracteres de bandera individuales en modo (es decir, los caracteres que preceden a la especificación ccs), la implementación glibc de fopen () y freopen () limita el número de caracteres examinados en modo a 7 (o, en glibc antes de 2.14, a 6, que no era suficiente para incluir posibles especificaciones tales como rbcmxe). La implementación actual de fdopen () analiza como máximo 5 caracteres en modo. Consulte también Referencia Byfopen Abre el archivo cuyo nombre se especifica en el nombre de archivo de parámetro y lo asocia con un flujo que puede identificarse en operaciones futuras mediante el puntero FILE devuelto. Las operaciones que se permiten en el flujo y cómo se realizan se definen mediante el parámetro de modo. La secuencia devuelta está totalmente almacenada en búfer por defecto si se sabe que no hace referencia a un dispositivo interactivo (véase setbuf). El puntero devuelto se puede desasociar del archivo llamando a fclose o freopen. Todos los archivos abiertos se cierran automáticamente al terminar el programa normal. El entorno en ejecución admite al menos archivos FOPENMAX abiertos simultáneamente. Parámetros filename Cadena C que contiene el nombre del archivo que se va a abrir. Su valor debe seguir las especificaciones de nombre de archivo del entorno en ejecución y puede incluir una ruta de acceso (si está soportado por el sistema). Cadena de modo C que contiene un modo de acceso a archivos. Puede ser: read: Abrir el archivo para las operaciones de entrada. El archivo debe existir. Write: Crear un archivo vacío para las operaciones de salida. Si ya existe un archivo con el mismo nombre, su contenido se descarta y el archivo se trata como un nuevo archivo vacío. Append: Abre el archivo para la salida al final de un archivo. Las operaciones de salida siempre escriben datos al final del archivo, expandiéndolo. Las operaciones de reposicionamiento (fseek, fsetpos, rebobinado) se ignoran. El archivo se crea si no existe. Read / update: Abra un archivo para actualizar (tanto para entrada como para salida). El archivo debe existir. Escribir / actualizar: Crear un archivo vacío y abrirlo para la actualización (tanto para la entrada y salida). Si ya existe un archivo con el mismo nombre, su contenido se descarta y el archivo se trata como un nuevo archivo vacío. Append / update: Abre un archivo para actualizar (tanto para entrada como salida) con todas las operaciones de salida escribiendo datos al final del archivo. Las operaciones de reposición (fseek, fsetpos, rebobinar) afectan a las operaciones de entrada siguientes, pero las operaciones de salida mueven la posición de nuevo al final del archivo. El archivo se crea si no existe. Con los especificadores de modo arriba, el archivo está abierto como un archivo de texto. Para abrir un archivo como un archivo binario. Un carácter b tiene que ser incluido en la cadena de modo. Este carácter b adicional se puede añadir al final de la cadena (haciendo así los siguientes modos compuestos: rb, wb, ab, rb, wb, ab) o insertarse entre la letra y el signo para los modos mixtos (rb, Wb, ab). El nuevo estándar C (C2011, que no forma parte de C) añade un nuevo subespecificador estándar (x), que puede añadirse a cualquier especificador w (para formar wx, wbx, wx o wbx / wbx). Este subespecificador obliga a la función a fallar si el archivo existe, en lugar de sobrescribirlo. Si los caracteres adicionales siguen la secuencia, el comportamiento depende de la implementación de la biblioteca: algunas implementaciones pueden ignorar caracteres adicionales para que, por ejemplo, se acepte un t adicional (a veces utilizado para indicar explícitamente un archivo de texto). En algunas implementaciones de biblioteca, abrir o crear un archivo de texto con modo de actualización puede tratar el flujo en su lugar como un archivo binario. Los archivos de texto son archivos que contienen secuencias de líneas de texto. Dependiendo del entorno donde se ejecuta la aplicación, puede producirse una conversión de caracteres especiales en las operaciones de entrada / salida en modo texto para adaptarlas a un formato de archivo de texto específico del sistema. Aunque en algunos entornos no se producen conversiones y tanto los archivos de texto como los binarios se tratan de la misma manera, el uso del modo apropiado mejora la portabilidad. Para los archivos abiertos a la actualización (aquellos que incluyen un signo), en los que se permiten las operaciones de entrada y salida, el flujo se vacía (fflush) o reposicionado antes de una operación de lectura que sigue a una operación de escritura. La corriente se reposicionará antes de una operación de escritura que siga una operación de lectura (siempre que esa operación no llegue al final del archivo). Valor devuelto Si el archivo se abre correctamente, la función devuelve un puntero a un objeto FILE que se puede utilizar para identificar el flujo en futuras operaciones. De lo contrario, se devuelve un puntero nulo. En la mayoría de las implementaciones de la biblioteca, la variable errno también se establece en un código de error específico del sistema en caso de fallo. Ejemplo
No comments:
Post a Comment