Как прочитать весь поток в std :: string? - PullRequest
66 голосов
/ 08 июля 2010

Я пытаюсь прочитать весь поток (несколько строк) в строку.

Я использую этот код, и он работает, но это оскорбляет мое чувство стиля ... Конечно, есть более простой способ?Может быть, использовать строковые потоки?

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.


На самом деле, ссылка const на строку тоже подойдет, и это может упростить ситуацию ...
const std::string &s(... a miracle occurs here...)

Ответы [ 6 ]

103 голосов
/ 08 июля 2010

Как насчет

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

(может быть однострочным, если не для MVP)

редактирование после 2011 года, этот подход теперь записан

std::string s(std::istreambuf_iterator<char>(stream), {});
23 голосов
/ 12 февраля 2011

Я опаздываю на вечеринку, но вот довольно эффективное решение:

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

Я провел некоторый бенчмаркинг, и оказалось, что метод std::istreambuf_iterator (, используемый в принятом ответе ) на самом деле намного медленнее. На gcc 4.4.5 с -O3 разница примерно в 4,5 раза на моей машине, и разрыв становится больше с более низкими настройками оптимизации.

16 голосов
/ 08 июля 2010

Вы могли бы сделать

std::string s;
std::ostringstream os;
os<<stream.rdbuf();
s=os.str();

но я не знаю, эффективнее ли это.

Альтернативная версия:

std::string s;
std::ostringstream os;
stream>>os.rdbuf();
s=os.str();
11 голосов
/ 08 июля 2010

Вы можете попробовать использовать что-то из алгоритмов. Я должен быть готов к работе, но вот очень быстрый удар по делу (должен быть лучший способ):

copy( istreambuf_iterator<char>(stream), istreambuf_iterator<char>(), back_inserter(s) );
0 голосов
/ 06 декабря 2016

Возможно это 1 строчка C ++ 11 решения:

std::vector<char> s{std::istreambuf_iterator<char>{in},{}};
0 голосов
/ 22 июля 2016

Хорошо, если вы ищете простой и «читаемый» способ сделать это. Я бы рекомендовал добавить / использовать некоторые высокоуровневые фреймворки в вашем проекте. Для этого я всегда использую Poco и Boost во всех своих проектах. В этом случае с Poco:

    string text;
    FileStream fstream(TEXT_FILE_PATH);
    StreamCopier::copyToString(fstream, text);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...