Как прочитать весь поток в строку std::?
Я пытаюсь прочитать весь поток (несколько строк) в строку.
Я использую этот код, и он работает, но это оскорбляет мое чувство стиля... Наверняка есть более простой способ? Может быть, с помощью струнных потоков?
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.
На самом деле, a
const
ссылка на строку будет делать также, и это может сделать вещи проще...
const std::string &s(... a miracle occurs here...)
6 ответов:
как о
std::istreambuf_iterator<char> eos; std::string s(std::istreambuf_iterator<char>(stream), eos);
(может быть один лайнер, если не для MVP)
после 2011 редактирования, этот подход теперь пишется
std::string s(std::istreambuf_iterator<char>(stream), {});
Я опаздываю на вечеринку, но вот довольно эффективное решение:
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 x разница на моей машине, и разрыв становится шире с более низкими настройками оптимизации.
вы могли бы сделать
std::string s; std::ostringstream os; os<<stream.rdbuf(); s=os.str();
но я не знаю, если это более эффективно.
альтернативный вариант:
std::string s; std::ostringstream os; stream>>os.rdbuf(); s=os.str();
вы можете попробовать что-то из алгоритмов. Я должен подготовиться к работе, но вот очень быстрый удар по вещам (должен быть лучший способ):
copy( istreambuf_iterator<char>(stream), istreambuf_iterator<char>(), back_inserter(s) );
Ну, если вы ищете простой и читабельными способ сделать это. Я бы рекомендовал добавить / использовать некоторые рамки высокого уровня в вашем проекте. Для этого я всегда использую Poco и Boost на всех моих проектах. В этом случае, с Poco:
string text; FileStream fstream(TEXT_FILE_PATH); StreamCopier::copyToString(fstream, text);