C++ 如何将整个流读入std::vector?

C++ 如何将整个流读入std::vector?,c++,vector,stl,stream,ifstream,C++,Vector,Stl,Stream,Ifstream,我阅读了一篇演示如何使用以下一(两)行程序将整个流读入std::string的文章: 上述操作会产生编译器错误(VC2013): 1> d:\non svn\c++\library\i\file\filereader.cpp(62):错误C2440: '':无法从转换 “std::basic_ifstream>”到 'std::istreambuf_迭代器>'1> 有1>[1>\u Elem=uint8\u t 1>]1> 没有构造函数可以接受源类型或构造函数重载 决议模棱两可 ifstream

我阅读了一篇演示如何使用以下一(两)行程序将整个流读入std::string的文章:

上述操作会产生编译器错误(VC2013):

1> d:\non svn\c++\library\i\file\filereader.cpp(62):错误C2440: '':无法从转换 “std::basic_ifstream>”到 'std::istreambuf_迭代器>'1>
有1>[1>\u Elem=uint8\u t 1>]1>
没有构造函数可以接受源类型或构造函数重载 决议模棱两可


ifstream
char
的流,而不是
uint8\t
。您需要
basic\u ifstream
istreambuf\u迭代器
来匹配类型


前者在没有一定工作量的情况下可能无法工作,因为库只需要支持
char
wchar\u t
流;因此,您可能需要
istreambuf\u迭代器

,只是类型不匹配
ifstream
只是一个typedef:

typedef basic_ifstream<char> ifstream;
typedef basic_ifstream ifstream;
因此,如果您想使用不同的底层类型,只需告诉它:

std::basic_ifstream<uint8_t> stream(path, std::ios::in | std::ios::binary);    
auto eos = std::istreambuf_iterator<uint8_t>();
auto buffer = std::vector<uint8_t>(std::istreambuf_iterator<uint8_t>(stream), eos);
std::basic_ifstream(路径,std::ios::in | std::ios::binary);
自动eos=std::istreambuf_迭代器();
自动缓冲区=标准::向量(标准::istreambuf_迭代器(流),eos);
这对我很有用

或者,因为迪特玛说这可能有点粗略,你可以这样做:

auto stream = std::ifstream(...);
std::vector<uint8_t> data;

std::for_each(std::istreambuf_iterator<char>(stream),
              std::istreambuf_iterator<char>(),
              [&data](const char c){
                  data.push_back(c);
              });
auto-stream=std::ifstream(…);
std::矢量数据;
std::for_each(std::istreambuf_迭代器(流),
std::istreambuf_迭代器(),
[&数据](常量字符c){
数据。推回(c);
});

根据错误消息,
char
uint8\t
在编译器上是不同的。尝试改用
char
。@cdhowie
uint8\u t
unsigned char
,所以是的,在任何计算机上都不一样;)但是是的,这可能是一个模棱两可的强制转换,因为
ifstream
的输出是
char
。是的,它与char一起工作,但uint8\u t无论如何都是无符号char。@Robinson:没错
char
unsigned char
是不同的类型。@cdhowie
char
signed char
unsigned char
始终是三种不同的类型。。。。创建一个
std::basic_ifstream
是非常不平凡的@迪特马克·吕尔:说得好。我通常会避开I/O库的黑暗深处,所以记不清它到底支持什么。如果这真的有效,那就太令人惊讶了!它可能会编译,但我无法想象这会立即运行:为字符类型而不是
char
wchar\u t
创建流肯定不需要立即工作,因为不需要提供许多必要的方面。对于特定的需求,我希望至少缺少
std::codevt
(我不确定是否真的需要任何其他方面)。如果它不应该开箱即用,我想我不应该这样做。我想要区分的是二进制流和二进制数据以及文本流和文本数据。所以我打算用uint8_t表示二进制数据,用char表示文本。我想一切都使用char是惯用的…您可以简单地使用typedef,比如
typedef std::vector text\u vector
typedef std::vector binary\u vector
。虽然它们是同一类型的,但至少你的代码会根据你期望的数据类型在哪里进行自我记录。是的,我想我可以这样做。最简单的方法就是使用
std::istreambuf\u迭代器
初始化
std::vector
std::basic_ifstream<uint8_t> stream(path, std::ios::in | std::ios::binary);    
auto eos = std::istreambuf_iterator<uint8_t>();
auto buffer = std::vector<uint8_t>(std::istreambuf_iterator<uint8_t>(stream), eos);
auto stream = std::ifstream(...);
std::vector<uint8_t> data;

std::for_each(std::istreambuf_iterator<char>(stream),
              std::istreambuf_iterator<char>(),
              [&data](const char c){
                  data.push_back(c);
              });