¿Cuál es la forma más sencilla de escribir en stdout en modo binario?

3 minutos de lectura

avatar de usuario
jncraton

He estado tratando de averiguar la mejor manera de escribir datos binarios en la salida estándar desde un programa C. Funciona bien en Linux, pero tengo problemas cuando compilo en Windows porque “\n” se convierte en “\r\n”.

¿Existe una forma estándar de escribir en stdout en algún tipo de modo binario que evite la conversión de nueva línea? Si no, ¿cuál es la forma más sencilla de hacer que Windows deje de hacer esto?

Estoy usando GCC y MinGW, y escribo a stdout utilizando fwrite.

  • ¿Cómo estás produciendo cosas actualmente?

    –Oliver Charlesworth

    2 de junio de 2013 a las 23:47

  • has probado a usar fwrite en lugar de printf?

    – tay10r

    2 de junio de 2013 a las 23:47

  • Actualmente estoy usando fwrite.

    – jncratón

    2 de junio de 2013 a las 23:49

avatar de usuario
Joni

Puedes usar setmode(fileno(stdout), O_BINARY)

Envuélvalo en un ifdef si desea mantenerlo compatible con Linux.

Ver también: https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/setmode?view=vs-2017

  • freopen(NULL, "wb", stdout) también se puede usar y es portátil C. Sin embargo, puede tener efectos de truncamiento no deseados; consulte la sección Uso de la aplicación de pubs.opengroup.org/onlinepubs/9699919799/functions/freopen.html. Por lo que vale, creo que este texto está mal; cuando el nuevo nombre de archivo es NULL, no hay subyacente open operación y por lo tanto el texto sobre O_TRUNC no se aplica.

    – R.. GitHub DEJA DE AYUDAR A ICE

    3 de junio de 2013 a las 3:15


  • @R.. no puedes usar freopen con un NULL nombre de archivo en Windows, llamará al controlador de parámetros no válidos de acuerdo con esto: msdn.microsoft.com/en-us/library/wk2h68td.aspx y el comportamiento predeterminado del controlador de parámetros no válidos es bloquear la aplicación.

    – Vargas

    10/09/2014 a las 18:53


  • @Vargas: NULL no es un parámetro inválido para freopenasí que diría que es un error en MSVCRT…

    – R.. GitHub DEJA DE AYUDAR A ICE

    10/09/2014 a las 20:19

  • El enlace que publicó indica que está definido por la implementación para permitir que se vuelvan a abrir las transmisiones. Mi punto original es que esta no es una forma portátil de configurar el modo de transmisión en binario.

    – Vargas

    10/09/2014 a las 21:15


  • o si “fileno” no funciona -> valores sin formato: stdin:0, stdout:1, stderr:2 debido a la documentación de MSDN.

    – 18C

    27 de agosto de 2017 a las 19:43

Puedes hacer algo así (que es una especie de plataforma cruzada):

FILE *const in = fdopen(dup(fileno(stdin)), "rb");
FILE *const out = fdopen(dup(fileno(stdout)), "wb");
/* ... */
fclose(in);
fclose(out);

O puedes usar write() y read() llamadas del sistema directamente con fileno(stdin) y fileno(stdout). Esas llamadas al sistema operan en un nivel inferior y no realizan ninguna conversión. Pero tampoco tienen el almacenamiento en búfer que obtienes de FILE arroyos

  • la parte sobre write() parece estar mal, todavía obtengo conversiones de nueva línea usándolo

    – Michael Mrozek

    6 de febrero de 2018 a las 3:19

  • Lo más probable es que no uses la llamada al sistema write() es decir man -s 2 write. No hay modos de texto/binario en ese nivel.

    – maravilla.ratones

    6 de febrero de 2018 a las 6:29

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad