Чтение двоичных данных из std :: cin - PullRequest
14 голосов
/ 28 сентября 2011

Какой самый простой способ считывать двоичные (неформатированные) данные из std::cin в string или stringstream?

Ответы [ 7 ]

10 голосов
/ 28 сентября 2011

std::cin не открывается с ios_binary.Если вы должны использовать cin, то вам нужно снова открыть его, что не является частью стандарта.

Некоторые идеи здесь: http://compgroups.net/comp.unix.programmer/How-can-I-reopen-std-cin-and-std-cout-in-binary-mode.

После того, как он является двоичным, вы можете использовать cin.read() читать байты.Если вы знаете, что в вашей системе нет разницы между текстовым и двоичным (и вам не нужно быть переносимым), тогда вы можете просто использовать read, не беспокоясь.

7 голосов
/ 29 июня 2012

Для окон вы можете использовать функцию _setmode в сочетании с cin.read(), как уже упоминалось.

_setmode(_fileno(stdin), _O_BINARY);
cin.read(...);

См. Источник решения здесь: http://talmai -oliveira.blogspot.com / 2011/06 / чтение двоичных файлов-из-cin.html

2 голосов
/ 28 сентября 2011

cin.read будет хранить фиксированное количество байтов без какой-либо логической операции поиска разделителей того типа, который упоминал @Jason.

Однако в потоке все еще могут быть активные переводы, такие как CRLF -> NL, так что он все еще не идеален для двоичных данных.

2 голосов
/ 28 сентября 2011

В системе Unix / POSIX вы можете использовать метод cin.get() для чтения побайтно и сохранять данные в контейнер, такой как std::vector<unsigned int>, или вы можете использовать cin.read() для чтения фиксированное количество байтов в буфере. Вы также можете использовать cin.peek() для проверки любых индикаторов конца потока данных.

Имейте в виду, чтобы не использовать перегрузку operator>> для операций этого типа ... использование operator>> приведет к возникновению разрывов при каждом появлении символа разделителя, а также удалит символ разделителя из самого потока , Это будет включать в себя любые двоичные значения, которые эквивалентны пробелу, табуляции и т. Д. Таким образом, двоичные данные, которые вы в конечном итоге сохраните из std::cin, используя этот метод, не будут совпадать побайтно с байтом входного двоичного потока.

1 голос
/ 04 сентября 2017

Все предопределенные объекты iostream обязаны быть привязанными к соответствующим потокам C:

Объект cin управляет вводом из потокового буфера, связанного с объектом stdin, объявленным в <cstdio>.

http://eel.is/c++draft/narrow.stream.objects

и, следовательно, метод получения двоичных данных такой же, как и для C:

По сути, лучшее, что вы можете сделать, это:

freopen(NULL, "rb", stdin);

Это снова откроет стандартный ввод для того же потока ввода, но в двоичном формате Режим. В обычном режиме чтение из stdin в Windows преобразует \r\n (перевод строки Windows) на один символ ASCII 10. Использование Режим «rb» отключает это преобразование, чтобы вы могли правильно читать в двоичные данные.

https://stackoverflow.com/a/1599093/6049796

0 голосов
/ 03 ноября 2013

В windows / mingw / msys / bash, если вам нужно передать разные команды с двоичными потоками между ними, вам нужно манипулировать std :: cin и std :: cout как двоичными потоками.

Решение _setmode от Михаила отлично работает.

Используя MinGW, следующие заголовки:

#include <io.h>
#include <fcntl.h> 
0 голосов
/ 28 сентября 2011

cplusplus.com :

  • Неформатированный ввод

    Большинство других функций-членов класса istream используются для выполнениянеформатированный ввод, т. е. интерпретация символов, полученных с ввода, не производится.Эти функции-члены могут получить определенное количество символов из входной последовательности символов ( get , getline , peek , read , readsome ) ...

Как отметил Лу Франко, std :: cin не открывается с помощью std :: ios_base:: двоичная, но одна из этих функций может приблизить вас к нужному поведению.

...