从std::cin
读取二进制(非格式化)数据到string
或stringstream
的最简单方法是什么?
std::cin
未使用ios_binary打开。如果您必须使用cin,那么您需要重新打开它,这不是标准的一部分。
这里有一些想法:https://comp.unix.programmer.narkive.com/jeVj1j3I/how-can-i-reopen-std-cin-and-std-cout-in-binary-mode
一旦它是二进制的,你可以使用cin.read()
来读取字节。如果您知道在您的系统中,文本和二进制之间没有区别(并且您不需要可移植),那么您可以直接使用read,而不必担心。
对于windows,您可以将_setmode
函数与cin.read()
结合使用,如前所述。
_setmode(_fileno(stdin), _O_BINARY);
cin.read(...);
查看解决方案来源:http://talmai-oliveira.blogspot.com/2011/06/reading-binary-files-from-cin.html
cin.read
将存储固定数量的字节,不需要对@Jason提到的那种类型的分隔符进行任何逻辑搜索。
但是,流上可能仍然有活动的翻译,例如CRLF -> NL,因此它仍然不是二进制数据的理想选择。
在Unix/POSIX系统上,您可以使用cin.get()
方法逐字节读取数据并将数据保存到容器中,如std::vector<unsigned int>
,或者您可以使用cin.read()
以便将固定数量的字节读取到缓冲区中。您还可以使用cin.peek()
来检查任何数据流结束指示器。
请记住,避免使用operator>>
重载这种类型的操作…使用operator>>
将导致每当观察到分隔符字符时出现分隔符,并且还将从流本身删除分隔符。这将包括任何等同于空格、制表符等的二进制值。因此,使用该方法最终从std::cin
存储的二进制数据将不匹配输入二进制流。
所有预定义的iostream对象都必须绑定到相应的C流:
对象
cin
控制来自与对象stdin
关联的流缓冲区的输入,该对象在<cstdio>
中声明。
http://eel.is/c + +草案/narrow.stream.objects
,因此获取二进制数据的方法与C: 相同。https://stackoverflow.com/a/1599093/6049796基本上,你能做的最好的就是:
freopen(NULL, "rb", stdin);
这将重新打开stdin,使其成为相同的输入流,但是是二进制的模式。在正常模式下,从Windows上的stdin读取将转换
rn
(Windows换行符)到单个字符ASCII 10。使用"rb"模式禁用这种转换,以便您可以正确地读入二进制数据。
cplusplus.com:
- 非格式化输入
istream的大多数其他成员函数类用于执行未格式化的输入,即没有解释从输入中得到的字符。这些成员函数可以从输入字符中获取确定数目的字符序列(获取、getline peek,阅读,readsome )…
正如Lou Franco指出的,std::cin不是用std::ios_base::binary打开的,但是其中一个函数可能会让您接近您所寻找的行为。
在windows/mingw/msys/bash中,如果您需要在管道中使用二进制流来传输不同的命令,则需要将std::cin和std::cout作为二进制流来操作。
Mikhail的_setmode解决方案工作得很好。
使用MinGW,需要的头如下:
#include <io.h>
#include <fcntl.h>