txt leer guardarlo guardar datos crear como binarios binario arreglo archivos archivo c binary stdin

guardarlo - C leer stin binario



leer archivo binario c (7)

Estoy tratando de construir un simulador de tubería de instrucciones y estoy teniendo muchos problemas para comenzar. Lo que necesito hacer es leer el binario de la entrada estándar y luego almacenarlo en la memoria de alguna manera mientras manipulo los datos. Necesito leer en trozos de exactamente 32 bits uno tras otro.

¿Cómo leo en trozos de exactamente 32 bits a la vez? En segundo lugar, ¿cómo lo almaceno para su manipulación posterior?

Esto es lo que tengo hasta ahora, pero examinando los fragmentos binarios que leo más, simplemente no se ve bien, no creo que esté leyendo exactamente 32 bits como necesito.

char buffer[4] = { 0 }; // initialize to 0 unsigned long c = 0; int bytesize = 4; // read in 32 bits while (fgets(buffer, bytesize, stdin)) { memcpy(&c, buffer, bytesize); // copy the data to a more usable structure for bit manipulation later // more stuff buffer[0] = 0; buffer[1] = 0; buffer[2] = 0; buffer[3] = 0; // set to zero before next loop } fclose(stdin);

¿Cómo leo en 32 bits a la vez (todos ellos son 1/0, no hay líneas nuevas, etc.) y en qué los guardo, char[] está bien?

EDITAR: Soy capaz de leer el binario en pero ninguna de las respuestas produce los bits en el orden correcto; todos están destrozados, sospecho que el endianness y los problemas para leer y mover 8 bits alrededor (1 carácter) a la vez - esto necesita trabajar en Windows y C ...?


Considere utilizar SET_BINARY_MODE macro y setmode :

#ifdef _WIN32 # include <io.h> # include <fcntl.h> # define SET_BINARY_MODE(handle) setmode(handle, O_BINARY) #else # define SET_BINARY_MODE(handle) ((void)0) #endif

Más detalles sobre la macro SET_BINARY_MODE aquí: " Manejo de archivos binarios a través de E / S estándar "

Más detalles sobre setmode aquí: "_setmode "



Lo que necesitas es freopen() . De la página del manual:

Si el nombre de archivo es un puntero nulo, la función freopen () intentará cambiar el modo de la secuencia a la especificada por modo, como si el nombre del archivo actualmente asociado con la secuencia se hubiera utilizado. En este caso, el descriptor de archivo asociado con el flujo no necesita cerrarse si la llamada a freopen () tiene éxito. Está definido por la implementación qué cambios de modo están permitidos (si los hay) y bajo qué circunstancias.

Básicamente, lo mejor que puedes hacer es esto:

freopen(NULL, "rb", stdin);

Esto volverá a abrir stdin para que sea el mismo flujo de entrada, pero en modo binario. En el modo normal, la lectura de stdin en Windows convertirá /r/n (nueva línea de Windows) al único carácter ASCII 10. El uso del modo "rb" desactiva esta conversión para que pueda leer correctamente los datos binarios.

freopen() devuelve un freopen() , pero es el valor anterior (antes de ponerlo en modo binario), así que no lo use para nada. Después de eso, use fread() como se ha mencionado.

Sin embargo, en cuanto a sus inquietudes, es posible que no esté leyendo en "32 bits", pero si usa fread() , estará leyendo en 4 caracteres (lo que es lo mejor que puede hacer en C - char por lo menos está garantizado). 8 bits, pero algunas plataformas históricas e integradas tienen caracteres de 16 bits (algunos incluso tienen 18 o más). Si usas fgets() nunca leerás en 4 bytes. Leerá al menos 3 (dependiendo de si alguna de ellas es nueva línea), y el 4to byte será ''/0'' porque las cadenas en C terminan en fgets() y fgets() terminan en nul lo que lee (como una buena función ). Obviamente, esto no es lo que quieres, así que debes usar fread() .


No sé qué sistema operativo está ejecutando, pero normalmente no puede "abrir la entrada estándar en binario". Puedes probar cosas como

int fd = fdreopen (fileno (stdin), outfname, O_RDONLY | OPEN_O_BINARY);

Para intentar forzarlo. Entonces use

uint32_t opcode; read(fd, &opcode, sizeof (opcode));

Pero en realidad no lo he intentado yo mismo. :)


Tuve que juntar la respuesta a partir de los diversos comentarios del tipo de personas que se mencionan anteriormente, por lo que aquí hay un ejemplo que funciona completamente, solo para Windows, pero probablemente pueda traducir las cosas específicas de Windows a su plataforma.

#include "stdafx.h" #include "stdio.h" #include "stdlib.h" #include "windows.h" #include <io.h> #include <fcntl.h> int main() { char rbuf[4096]; char *deffile = "c://temp//outvideo.bin"; size_t r; char *outfilename = deffile; FILE *newin; freopen(NULL, "rb", stdin); _setmode(_fileno(stdin), _O_BINARY); FILE *f = fopen(outfilename, "w+b"); if (f == NULL) { printf("unable to open %s/n", outfilename); exit(1); } for (;; ) { r = fread(rbuf, 1, sizeof(rbuf), stdin); if (r > 0) { size_t w; for (size_t nleft = r; nleft > 0; ) { w = fwrite(rbuf, 1, nleft, f); if (w == 0) { printf("error: unable to write %d bytes to %s/n", nleft, outfilename); exit(1); } nleft -= w; fflush(f); } } else { Sleep(10); // wait for more input, but not in a tight loop } } return 0; }


fgets () está todo mal aquí. Está dirigido a texto ASCII legible por humanos, terminado por caracteres de fin de línea, no por datos binarios, y no obtendrá lo que necesita.

Hace poco hice exactamente lo que quieres usando la llamada read() . A menos que su programa haya cerrado explícitamente la entrada estándar, para el primer argumento (el descriptor de archivo), puede usar un valor constante de 0 para la entrada estándar. O, si está en un sistema POSIX (Linux, Mac OS X, o alguna otra variante moderna de Unix), puede usar STDIN_FILENO.


fread() adapta mejor para leer datos binarios.

Sí, char array está bien, si planea procesarlos por byte.