2010-11-11 17 views
10

Si hago algo como lo siguiente:¿Por qué no puedo leer los datos binarios de fstream con el operador >>?

ifstream file; 
file.open("somefile", ios::binary); 

unsigned int data; 

file >> data; 

Mi corriente siempre establece la failbit y la data permanecerá sin inicializar. Sin embargo, si leo un char o unsigned char, la transmisión es correcta. perror() me está diciendo "resultado demasiado grande".

Lo único que vi en Google fue una sugerencia que dice que operator>> no debe usarse para datos binarios (prefiera read()), pero creo que el operador es más limpio y fácil de usar, y no requiere lanzando todo.

¿Alguien puede explicar este problema?

Respuesta

10

El iostream extraction operator (>>) intenta interpretar cadenas numéricas separadas por espacios en blanco, no datos binarios. Hay muchas maneras diferentes de codificar un entero sin signo en forma binaria (por ejemplo, un 2's complement representation de 32 bits en little-endian byte order). Es por eso que debe usar las funciones read/write para operar en dichos búfers binarios.

Sin embargo, nada le impide implementar su propia clase para serializar datos binarios en la forma que desee utilizando los operadores de inserción y extracción. Tal clase probablemente usaría la función de lectura de un objeto ifstream internamente. Alternativamente, el boost serialization library ya puede contener exactamente lo que desea.

0

Se debe realizar tal como lo describe. Sin embargo, los diseñadores estándar de C++ no son muy elegantes. De hecho, hay muchos defectos en el diseño de C++, incluso C++ 11 y C++ 14 tienen muchos defectos.

El C++ ideales diseño debe ser que:

1.Para archivo de texto:

ifstream fin_txt("input.txt"); 
int i; 
float j; 
double k; 
fin_txt >> i >> j >> k; 

Esto permitirá la lectura en 3 cadenas y analizar en entero, flotante y doble, y almacenarlos en i, j y k respectivamente.

2.A archivo binario:

ifstream fin_txt("input.bin", ios::binary); 
int i; 
float j; 
double k; 
fin_txt >> i >> j >> k; 

Esto permitirá la lectura de 4/8 bytes (dependiendo de si int es de 32 bits o 64 bits), 4 bytes y 8 bytes de datos binarios y almacenarlos en i, j y k, respectivamente.

Desafortunadamente, el diseño actual es informar un error para el Caso 2. Tal vez esto se puede lograr en C++ 22.

+0

Tiene la razón por la cual es así en su respuesta: "dependiendo de si int es de 32 bits o de 64 bits". Actualmente, el código que usa '' es portable, su propuesta no lo es. – Caleth

Cuestiones relacionadas