Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read binary data from std::cin

What is the easiest way to read binary (non-formated) data from std::cin into either a string or a stringstream?

like image 531
Allan Avatar asked Sep 28 '11 18:09

Allan


5 Answers

std::cin is not opened with ios_binary. If you must use cin, then you need to reopen it, which isn't part of the standard.

Some ideas here: https://comp.unix.programmer.narkive.com/jeVj1j3I/how-can-i-reopen-std-cin-and-std-cout-in-binary-mode

Once it's binary, you can use cin.read() to read bytes. If you know that in your system, there is no difference between text and binary (and you don't need to be portable), then you can just use read without worrying.

like image 161
Lou Franco Avatar answered Oct 11 '22 16:10

Lou Franco


For windows, you can use the _setmode function in conjunction with cin.read(), as already mentioned.

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

See solution source here: http://talmai-oliveira.blogspot.com/2011/06/reading-binary-files-from-cin.html

like image 36
Mikhail Avatar answered Oct 11 '22 15:10

Mikhail


cin.read would store a fixed number of bytes, without any logic searching for delimiters of the type that @Jason mentioned.

However, there may still be translations active on the stream, such as CRLF -> NL, so it still isn't ideal for binary data.

like image 27
Ben Voigt Avatar answered Oct 11 '22 16:10

Ben Voigt


On a Unix/POSIX system, you can use the cin.get() method to read byte-by-byte and save the data into a container like a std::vector<unsigned int>, or you can use cin.read() in order to read a fixed amount of bytes into a buffer. You could also use cin.peek() to check for any end-of-data-stream indicators.

Keep in mind to avoid using the operator>> overload for this type of operation ... using operator>> will cause breaks to occur whenever a delimiter character is observed, and it will also remove the delimiting character from the stream itself. This would include any binary values that are equivalent to a space, tab, etc. Thus the binary data your end up storing from std::cin using that method will not match the input binary stream byte-for-byte.

like image 2
Jason Avatar answered Oct 11 '22 15:10

Jason


All predefined iostream objects are obligated to be bound to corresponding C streams:

The object cin controls input from a stream buffer associated with the object stdin, declared in <cstdio>.

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

and thus the method of obtaining binary data is same as for C:

Basically, the best you can really do is this:

freopen(NULL, "rb", stdin);

This will reopen stdin to be the same input stream, but in binary mode. In the normal mode, reading from stdin on Windows will convert \r\n (Windows newline) to the single character ASCII 10. Using the "rb" mode disables this conversion so that you can properly read in binary data.

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

like image 1
Euri Pinhollow Avatar answered Oct 11 '22 15:10

Euri Pinhollow