кто-либо мог сказать мне о некоторых практических примерах при использовании строковых потоков в C++, т.е. приписывания и вывода к строковому потоку с помощью потоковой вставки и потоковых операторов извлечения?
Вы можете использовать строковые потоки для преобразования всего, что реализует operator <<
в строку:
#include <sstream>
template<typename T>
std::string toString(const T& t)
{
std::ostringstream stream;
stream << t;
return stream.str();
}
или даже
template <typename U, typename T>
U convert(const T& t)
{
std::stringstream stream;
stream << t;
U u;
stream >> u;
return u;
}
Они могут быть использованы везде, где может быть использован обычный поток.
Так что в ситуациях, когда вы читаете из файла, вы потенциально можете читать из потока строк.
void compile(std::istream& str)
{
CPlusPlusLexer lexer(str);
CPlusPlusParser parser(lexer);
BackEnd backend(parser);
backend.compile();
}
int main()
{
std::fstream file("Plop.cpp");
compile(file);
std::stringstream test("#include <iostream>\n int main() { std::cout << \"H World\n\";}");
compile(test);
}
Я использую их в основном как буферы памяти, при создании сообщений:
if(someVector.size() > MAX_SIZE)
{
ostringstream buffer;
buffer << "Vector should not have " << someVector.size() << " eleements";
throw std::runtime_error(buffer.str());
}
или для построения сложных строк:
std::string MyObject::GenerateDumpPath()
{
using namespace std;
std::ostringstream dumpPath;
// add the file name
dumpPath << "\\myobject."
<< setw(3) << setfill('0') << uniqueFileId
<< "." << boost::lexical_cast<std::string>(state)
<< "_" << ymd.year
<< "." << setw(2) << setfill('0') << ymd.month.as_number()
<< "." << ymd.day.as_number()
<< "_" << time.hours()
<< "." << time.minutes()
<< "." << time.seconds()
<< ".xml";
return dumpPath.str();
}
Это полезно, потому что переносит всю расширяемость std::stream
s на использование символьных буферов (расширяемость ostreams и поддержка локалей, скрытое управление буферной памятью и так далее).
Другой пример, который я видел, - это отчет об ошибках в библиотеке gsoap, использующий инъекцию зависимостей: soap_stream_fault принимает параметр ostream& для сообщения об ошибках.
При желании вы можете передать ему std::cerr, std::cout или реализацию std::ostringstream (я использую его с реализацией std::ostringstream).
Помимо преимуществ, есть еще один момент, который следует тщательно учитывать , если вы используете gcc 4.3.1. Я не проверял предыдущие версии gcc.