2010-11-11 4 views
10

Si je fais quelque chose comme ce qui suit:Pourquoi ne puis-je pas lire les données binaires de fstream avec l'opérateur >>?

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

unsigned int data; 

file >> data; 

Mon flux sera toujours mis l'failbit et le data demeurera non initialisée. Cependant, si je lis un char ou unsigned char à la place, le flux est bon. perror() me dit "résultat trop grand". La seule chose que j'ai vu sur Google était une suggestion disant que operator>> ne devrait pas être utilisé pour des données binaires (préférez read()), mais je trouve l'opérateur plus propre et plus facile à utiliser - et il ne nécessite pas couler tout.

Quelqu'un peut-il expliquer ce problème?

Répondre

10

Le iostream extraction operator (>>) tente d'interpréter des chaînes numériques séparées par des espaces et non par des données binaires. Il existe de nombreuses manières différentes de coder un entier non signé sous forme binaire (par exemple un 2's complement representation 32 bits dans little-endian byte order). C'est pourquoi vous devez utiliser les fonctions read/write pour fonctionner sur ces tampons binaires. Cependant, rien ne vous empêche d'implémenter votre propre classe pour la sérialisation des données binaires sous la forme que vous souhaitez en utilisant les opérateurs d'insertion et d'extraction. Une telle classe utiliserait probablement la fonction de lecture d'un objet ifstream en interne. Alternativement, le boost serialization library peut déjà contenir exactement ce que vous voulez.

0

Cela doit être fait comme décrit par vous. Cependant, les concepteurs standards C++ ne sont pas très élégants. En fait, il y a beaucoup de failles dans la conception de C++, même C++ 11 et C++ 14 a beaucoup de défauts.

La conception C++ idéal devrait être que:

fichier texte 1.Pour:

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

Cela lu dans 3 chaînes et analyser en entier, float et double, et de les stocker dans i, j et k respectivement.

2.Aux fichier binaire:

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

Ceci va lire dans 4/8 octets (selon que int est de 32 bits ou 64 bits), 4 octets et 8 octets de données binaires et de les stocker en i, j et k respectivement.

Malheureusement, la conception actuelle est de signaler une erreur pour le cas 2. Peut-être que cela peut être réalisé en C++ 22.

+0

Vous avez la raison pour laquelle c'est ainsi dans votre réponse: "selon que int est 32 bits ou 64 bits". Actuellement, le code utilisant '' est portable, votre proposition ne l'est pas. – Caleth

Questions connexes