Чтение двоичных данных из std::cin
Какой самый простой способ чтения двоичных (неформатированных) данных из std::cin
либо в string
или stringstream
?
7 ответов
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, не беспокоясь.
Для окон вы можете использовать _setmode
функция в сочетании с cin.read()
, как уже упоминалось.
_setmode(_fileno(stdin), _O_BINARY);
cin.read(...);
См. Источник решения здесь: http://talmai-oliveira.blogspot.com/2011/06/reading-binary-files-from-cin.html
Все предопределенные объекты 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" отключает это преобразование, чтобы вы могли правильно читать двоичные данные.
/questions/5815252/c-chitat-dvoichnyij-standart/5815273#5815273
В системе Unix/POSIX вы можете использовать cin.get()
метод для чтения побайтно и сохранения данных в контейнер, как std::vector<unsigned int>
или вы можете использовать cin.read()
для того, чтобы прочитать фиксированное количество байтов в буфер. Вы также можете использовать cin.peek()
проверить наличие любых индикаторов конца потока данных.
Имейте в виду, чтобы избежать использования operator>>
перегрузка для этого типа операции... используя operator>>
будет вызывать разрывы всякий раз, когда наблюдается символ разделителя, и он также удалит символ разделителя из самого потока. Это будет включать любые двоичные значения, которые эквивалентны пробелу, табуляции и т. Д. Таким образом, двоичные данные, которые вы в конечном итоге сохраните std::cin
использование этого метода не будет соответствовать байту за байтом входного двоичного потока.
cin.read
будет хранить фиксированное количество байтов, без какой-либо логики поиска разделителей типа, который упоминал @Jason.
Тем не менее, в потоке все еще могут быть активные переводы, такие как CRLF -> NL, поэтому он все еще не идеален для двоичных данных.
Неформатированный ввод
Большинство других функций-членов класса istream используются для выполнения неформатированного ввода, т. Е. Не выполняется интерпретация символов, полученных из ввода. Эти функции-члены могут получить определенное количество символов из входной последовательности символов ( get, getline, peek, read, readsome)...
Как отметил Лу Франко, std:: cin не открывается с помощью std::ios_base::binary, но одна из этих функций может приблизить вас к тому поведению, которое вы ищете.
В windows/mingw/msys/bash, если вам нужно передать различные команды с двоичными потоками между ними, вы должны манипулировать std:: cin и std:: cout как двоичные потоки.
Решение _setmode от Михаила работает отлично.
Используя MinGW, следующие заголовки:
#include <io.h>
#include <fcntl.h>