【问题标题】:How to read entire stream into a std::vector?如何将整个流读入 std::vector?
【发布时间】:2014-12-22 17:38:45
【问题描述】:

我阅读了an answer here,它展示了如何使用以下一(二)个衬垫将整个流读入 std::string:

std::istreambuf_iterator<char> eos;    
std::string s(std::istreambuf_iterator<char>(stream), eos);

对于类似将二进制流读入std::vector 的操作,我为什么不能简单地将char 替换为uint8_t 并将std::string 替换为std::vector

auto stream = std::ifstream(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);

以上产生编译器错误(VC2013):

1>d:\non-svn\c++\library\i\file\filereader.cpp(62): 错误 C2440: '' : 不能从 'std::basic_ifstream>' 到 'std::istreambuf_iterator>' 1>
与 1> [ 1> _Elem=uint8_t 1> ] 1>
没有构造函数可以采用源类型或构造函数重载 分辨率不明确

【问题讨论】:

  • 根据错误消息,charuint8_t 在您的编译器上不是一回事。尝试改用char
  • @cdhowie uint8_tunsigned char,所以是的,在任何计算机上都不一样 ;) 但是,这可能是一个模棱两可的演员阵容,因为 ifstream 的输出是 char .
  • 是的,它适用于 char 但 uint8_t 无论如何都是 unsigned char。
  • @Robinson:没错。 charunsigned char 是不同的类型。
  • @cdhowie charsigned charunsigned char 始终是 3 种不同的类型。

标签: c++ vector stl stream ifstream


【解决方案1】:

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

typedef basic_ifstream<char> 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);

这对我有用。

或者,由于 Dietmar 说这可能有点粗略,您可以这样做:

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);
              });

【讨论】:

  • 如果这真的有效,那就太令人惊讶了!它可以编译,但我无法想象它可以立即运行:为charwchar_t 以外的字符类型创建流当然不必马上工作因为不必提供许多必要的方面。对于特定需求,我希望至少缺少std::codecvt&lt;uint8_t, char, std::mbstate_t&gt;(我不确定是否真的需要任何其他方面)。
  • 如果它不应该开箱即用,我想我不应该这样做。我想要区分二进制流和二进制数据以及文本流和文本数据。所以我打算将 uint8_t 用于二进制数据,将 char 用于文本。我想对所有事情都使用 char 是惯用的......
  • 你可以简单地使用像typedef std::vector&lt;char&gt; text_vectortypedef std::vector&lt;char&gt; binary_vector这样的typedef。虽然它们在底层是相同的类型,但至少您的代码会根据您期望在哪里获得什么样的数据来自我记录。
  • 是的,我想我可以这样做。
  • 最简单的方法就是使用std::istreambuf_iterator&lt;char&gt;来初始化std::vector&lt;uint8_t&gt;
【解决方案2】:

ifstreamchar 的流,而不是uint8_t。您需要 basic_ifstream&lt;uint8_t&gt;istreambuf_iterator&lt;char&gt; 来匹配类型。

如果没有一些工作,前者可能无法工作,因为该库只需要支持charwchar_t 的流;所以你可能想要istreambuf_iterator&lt;char&gt;

【讨论】:

  • ... 并创建一个 std::basic_ifstream&lt;uint8_t&gt; 相当重要!
  • @DietmarKühl:好点。我通常会避开 I/O 库的模糊深度,所以不记得它支持什么。
猜你喜欢
  • 2011-03-13
  • 1970-01-01
  • 2016-04-17
  • 1970-01-01
  • 1970-01-01
  • 2013-01-01
  • 2020-11-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多