Как очистить переменную stringstream?
Я уже пробовал несколько вариантов,
std::stringstream m;
m.empty();
m.clear();
но ни один из них не сработал.
5 ответ(ов)
Для всех типов стандартной библиотеки функция-член empty()
является запросом, а не командой, т.е. она отвечает на вопрос "пуст ли ты?" и не предназначена для команды "пожалуйста, очисти своё содержимое".
Функция-член clear()
унаследована от ios
и используется для сброса состояния ошибки потока. Например, если поток файла имеет установленное состояние ошибки eofbit
(конец файла), то вызов clear()
восстановит состояние ошибки на goodbit
(без ошибок).
Для очистки содержимого stringstream
использование следующего кода:
m.str("");
является правильным, хотя более эффективным вариантом будет:
m.str(std::string());
так как в этом случае вы избегаете вызова конструктора std::string
, который принимает const char*
. Однако любой современный компилятор должен генерировать одинаковый код в обоих случаях, поэтому я рекомендовал бы использовать тот вариант, который читается лучше.
Наиболее надежный способ, который не зависит от компилятора, будет выглядеть следующим образом:
m = std::stringstream();
Таким образом, вы создаете новый объект std::stringstream
и присваиваете его переменной m
. Это гарантирует, что m
будет инициализирован корректно вне зависимости от используемого компилятора.
Ваша строка кода m.str("");
действительно кажется рабочей. Этот метод обычно используется для обнуления содержимого стрима. Если m
— это объект, который поддерживает метод str()
, например, std::stringstream
из библиотеки <sstream>
, то вызов m.str("")
устанавливает содержимое стрима в пустую строку.
Таким образом, после выполнения этой команды вы очистите все данные, которые были записаны в m
. Если у вас есть дополнительные вопросы или требуется уточнение по работе с std::stringstream
или подобными классами, не стесняйтесь спрашивать!
В вашем коде вы создаете несколько объектов std::stringstream
внутри отдельных блоков. Каждый раз, когда вы создаете новый блок, объект ss
будет уничтожен после выхода из блока, и память, занимаемая этим объектом, будет освобождена. Это означает, что вы создаете новую строку для каждого блока, но если ваша цель — сохранить строку, которая складывается из всех частей, то такой подход не совсем эффективен.
Вот как можно переписать ваш код, чтобы избежать ненужного создания объектов и объединять строки:
#include <sstream>
#include <string>
std::string result;
{
std::stringstream ss;
ss << "what";
result += ss.str();
}
{
std::stringstream ss;
ss << "the";
result += ss.str();
}
{
std::stringstream ss;
ss << "heck";
result += ss.str();
}
Однако, если вы хотите сделать это еще проще и более эффективно, вы можете использовать один объект std::stringstream
вне блоков, вот пример:
#include <sstream>
#include <string>
std::stringstream ss;
ss << "what";
ss << "the";
ss << "heck";
std::string result = ss.str(); // Здесь вы получаете итоговую строку
Таким образом, вы будете использовать только один объект stringstream
, что уменьшает накладные расходы на создание и уничтожение объектов.
Вот мой опыт по данной проблеме:
У меня была программа с меню, которая, если её выполнять итеративно по запросу пользователя, заполняла переменную stringstream
. Всё работало нормально при первом запуске кода, но при последующих запусках stringstream
не очищался. После 2 часов проб и ошибок и поисков в Google я нашёл решение. Две строки кода, приведенные ниже, действительно очищали переменную stringstream
каждый раз перед её заполнением. Примечание: использовать каждую строку по отдельности не сработало.
// очищаем переменную stringstream
sstm.str("");
sstm.clear();
// заполняем переменную stringstream
sstm << "crap" << "morecrap";
Надеюсь, это поможет кому-то решить похожую проблему!
Что такое Правило трёх?
Разница между const int*, const int * const и int * const?
Имеют ли круглые скобки после имени типа значение при использовании new?
Как удалить элемент из std::vector<> по индексу?
`unsigned int` против `size_t`: когда и что использовать?