如何将整个流读入std :: string?

Rod*_*ddy 68 c++ string stream

我正在尝试将整个流(多行)读成字符串.

我正在使用这个代码,它有效,但它冒犯了我的风格......当然有一种更简单的方法吗?也许使用stringstreams?

void Obj::loadFromStream(std::istream & stream)
{ 
  std::string s;

  std::streampos p = stream.tellg();  // remember where we are

  stream.seekg(0, std::ios_base::end); // go to the end
  std::streamoff sz = stream.tellg() - p;  // work out the size
  stream.seekg(p);        // restore the position

  s.resize(sz);          // resize the string
  stream.read(&s[0], sz);  // and finally, read in the data.
Run Code Online (Sandbox Code Playgroud)


实际上,const对字符串的引用也可以,这可能会使事情变得更容易......

const std::string &s(... a miracle occurs here...)
Run Code Online (Sandbox Code Playgroud)

Cub*_*bbi 107

怎么样

std::istreambuf_iterator<char> eos;
std::string s(std::istreambuf_iterator<char>(stream), eos);
Run Code Online (Sandbox Code Playgroud)

(如果不是MVP,可能是单线)

在2011年后编辑,这种方法现在拼写

std::string s(std::istreambuf_iterator<char>(stream), {});
Run Code Online (Sandbox Code Playgroud)

  • @Roddy:字符串是从istreambuf_iterator开始的范围连接,它迭代未格式化的字符,直到它变得等于默认构造的输入迭代器,即"end of stream".参见Scott Meyers,Effective STL Item 29:考虑istreambuf_iterators进行逐字符输入 (13认同)
  • 如果您愿意,它仍然可以是单行的:`string s = string(...)`。 (2认同)
  • 取自 [std::istream_iterator 文档](http://en.cppreference.com/w/cpp/iterator/istream_iterator) “注:读取字符时,std::istream_iterator 默认跳过空格(除非用 std 禁用: :noskipws 或等价物),而 std::istreambuf_iterator 没有。此外,std::istreambuf_iterator 更有效,因为它避免了每个字符构造和销毁一次哨兵对象的开销。” (2认同)
  • 由于模板参数推导,您现在也可以删除“&lt;char&gt;”。 (2认同)

Joe*_*ams 24

我迟到了,但这是一个相当有效的解决方案:

std::string gulp(std::istream &in)
{
    std::string ret;
    char buffer[4096];
    while (in.read(buffer, sizeof(buffer)))
        ret.append(buffer, sizeof(buffer));
    ret.append(buffer, in.gcount());
    return ret;
}
Run Code Online (Sandbox Code Playgroud)

我做了一些基准测试,事实证明该std::istreambuf_iterator技术(被接受的答案使用)实际上要慢得多.在gcc 4.4.5上-O3,它在我的机器上差异大约是4.5倍,并且随着优化设置的降低,差距变得更大.

  • 使用string :: reserve(size_t)可以提高效率. (8认同)
  • 确实比我的回答更有效率,因为正确的块状读取将是.OP想要"简单"的方式,这通常与"快速"相反. (5认同)
  • @BarnabasSzabolcs:-Os 用于紧凑代码,-O3 用于积极优化,而 -O2 不那么积极。请参阅 https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html (2认同)

Mat*_*lia 18

你可以做到

std::string s;
std::ostringstream os;
os<<stream.rdbuf();
s=os.str();
Run Code Online (Sandbox Code Playgroud)

但我不知道它是否更有效率.

替代版本:

std::string s;
std::ostringstream os;
stream>>os.rdbuf();
s=os.str();
Run Code Online (Sandbox Code Playgroud)

  • 谢谢。作为一个解决方案,我发现这非常简单且可读,并且我正在使用它。不过,我接受了 Cubbi 的回答,因为我从中学到了很多东西! (2认同)

whe*_*ies 11

您可以尝试使用算法中的某些内容.我必须为工作做好准备,但这里有很快的事情(必须有更好的方法):

copy( istreambuf_iterator<char>(stream), istreambuf_iterator<char>(), back_inserter(s) );
Run Code Online (Sandbox Code Playgroud)