如何将整个文件读入 C 中的 std::string ?

新手上路,请多包涵

如何将文件读入 std::string ,即一次读取整个文件?

调用者应指定文本或二进制模式。该解决方案应符合标准、可移植且高效。它不应该不必要地复制字符串的数据,并且应该避免在读取字符串时重新分配内存。

One way to do this would be to stat the filesize, resize the std::string and fread() into the std::string ’s const_cast<char*>() ‘ed data() 。这要求 std::string 的数据是连续的,这不是标准要求的,但似乎所有已知实现都是如此。更糟糕的是,如果以文本模式读取文件,则 std::string 的大小可能不等于文件的大小。

A fully correct, standard-compliant and portable solutions could be constructed using std::ifstream ’s rdbuf() into a std::ostringstream and from there into a std::string 。但是,这可能会复制字符串数据和/或不必要地重新分配内存。

  • 所有相关的标准库实现是否足够聪明,可以避免所有不必要的开销?
  • 还有另一种方法吗?
  • 我是否错过了一些已经提供所需功能的隐藏 Boost 功能?
 void slurp(std::string& data, bool is_binary)

原文由 wilbur_m 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 625
1 个回答
std::string get(std::string_view const& fn)
{
  struct filebuf: std::filebuf
  {
    using std::filebuf::egptr;
    using std::filebuf::gptr;

    using std::filebuf::gbump;
    using std::filebuf::underflow;
  };

  std::string r;

  if (filebuf fb; fb.open(fn.data(), std::ios::binary | std::ios::in))
  {
    r.reserve(fb.pubseekoff({}, std::ios::end));
    fb.pubseekpos({});

    while (filebuf::traits_type::eof() != fb.underflow())
    {
      auto const gptr(fb.gptr());
      auto const sz(fb.egptr() - gptr);

      fb.gbump(sz);
      r.append(gptr, sz);
    }
  }

  return r;
}

原文由 user1095108 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题