Чтение двоичных данных из 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, поэтому он все еще не идеален для двоичных данных.

cplusplus.com:

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

    Большинство других функций-членов класса 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> 
Другие вопросы по тегам