Почему я не могу прочитать двоичные данные fstream с помощью оператора >>? - PullRequest
14 голосов
/ 11 ноября 2010

Если я сделаю что-то вроде следующего:

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

unsigned int data;

file >> data;

Мой поток всегда установит failbit, а data останется неинициализированным.Однако, если я вместо этого прочитал char или unsigned char, поток в порядке.perror() говорит мне "результат слишком велик".

Единственное, что я увидел в Google, было предложение о том, что operator>> не следует использовать для двоичных данных (предпочтительнее read()), но я считаю, что оператор более чистый и простой в использовании -и это не требует кастинга всего.

Может кто-нибудь объяснить эту проблему?

Ответы [ 2 ]

11 голосов
/ 11 ноября 2010

Оператор извлечения iostream (>>) пытается интерпретировать числовые строки, разделенные пробелами, а не двоичными данными. Существует много различных способов кодирования целого числа без знака в двоичной форме (например, 32-битное представление дополнения 2 в порядок байтов младшего байта ). Вот почему вы должны использовать функции read / write для работы с такими двоичными буферами.

Однако ничто не мешает вам реализовать свой собственный класс для сериализации двоичных данных в любой форме, которую вы пожелаете, используя операторы вставки и извлечения. Такой класс, вероятно, будет использовать функцию чтения внутреннего объекта ifstream. Кроме того, библиотека расширенной сериализации может уже содержать именно то, что вам нужно.

0 голосов
/ 13 апреля 2016

Это должно быть сделано, как описано вами. Тем не менее, стандартные дизайнеры C ++ не очень элегантны. На самом деле, в дизайне C ++ есть много недостатков, даже в C ++ 11 и C ++ 14 есть много недостатков.

Идеальный дизайн C ++ должен быть таким:

1.Для текстового файла:

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

Это будет читать в 3 строки и разбирать на целое, float и double, и сохранять их в i, j и k соответственно.

2.Для двоичного файла:

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

Это будет считывать 4/8 байт (в зависимости от того, является ли int 32-битным или 64-битным), 4-байтовыми и 8-байтовыми двоичными данными и сохранять их в i, j и k соответственно.

К сожалению, текущий дизайн должен сообщить об ошибке для случая 2. Возможно, это может быть достигнуто в C ++ 22.

...