Я пытаюсь использовать объект ostream для записи либо в файловый поток пользовательского ввода на основе строкового потока (аналогично fmemopen
в Linux).
Я понял, что ostream не принимает объекты stringstream или fstream, а вместо этого принимает stringbug или filebuf.
Я попробовал следующий код:
char content[] = "This is a test";
if (isFile)
{
filebuf fp;
fp.open(filename, ios::out);
ostream os(&fp);
os << content;
fp.close();
}
else
{
stringbuf str;
ostream os(&str);
os << content;
}
Это отлично работает в условии if else, но я хотел бы использовать ostream os
как os << content
вне условия if else. Однако проблема в том, что я не могу глобально определить ostream os, поскольку для ostream нет такого конструктора.
Есть ли способ обойти это?
Это то, с чем я могу работать. Есть ли способ по умолчанию инициализировать insertdata(ostream& os)
, чтобы сказать insertdata(ostream& os = ofstream("temp.txt",ios::out)
? Это дает мне ошибку. Это работает, если я делаю const ostream& os
, но тогда os.write выдает ошибку компиляции.
@Trancey, неконстантная ссылка не может быть привязана к временному объекту. Кроме того, это не тот сценарий, в котором имеет смысл использовать значение по умолчанию. Вызывающий должен указать, в какой тип потока функция должна писать.
С этим можно справиться несколькими способами.
Использование вспомогательной функции:
void write(ostream &os, const char *content)
{
os << content
}
...
char content[] = "This is a test";
if (isFile)
{
ofstream ofs(filename);
write(ofs, content);
}
else
{
ostringstream oss;
write(oss, content);
string s = oss.str();
// use s as needed...
}
В качестве альтернативы, используя лямбда:
char content[] = "This is a test";
auto write = [](ostream &os, const char *content){ os << content; }
if (isFile)
{
ofstream ofs(filename);
write(ofs, content);
}
else
{
ostringstream oss;
write(oss, content);
string s = oss.str();
// use s as needed...
}
Вместо этого используйте указатель:
char content[] = "This is a test";
std::unique_ptr<ostream> os;
if (isFile)
os = std::make_unique<ofstream>(filename);
else
os = std::make_unique<ostringstream>();
*os << content;
if (!isFile)
{
string s = static_cast<ostringstream*>(os.get())->str(); // or: static_cast<ostringstream&>(*os).str()
// use s as needed...
}
Это помогает! *os << content
для ostringstream, можно ли это записать в объект ostringstream? Кажется, я могу получить его из указателя rdbuf streambuf, но я не могу поместить его в стандартную строку или stringstream.
Моя ошибка, *oss << content
должно было быть *os << content
. И да, это может написать ostringstream
, так как это потомок ostream
. Чтобы впоследствии получить string
, вы можете привести ostream
обратно к ostringstream
, чтобы вызвать его метод str()
. Я обновил свой ответ, чтобы показать, что
Отделите запись данных от настройки механизма вывода. Напишите функцию, которая вставляет данные в поток. Эта функция должна принимать
std::ostream
по ссылке и записывать туда данные. Когда вы вызываете функцию, передайтеstd::ofstream
илиstd::ostringstream
, в зависимости от ситуации.