Как вы очищаете переменную stringstream?

486

Я уже пробовал несколько вещей,

std::stringstream m;
m.empty();
m.clear();

оба из которых не работают.

CodingWithoutComments
источник

Ответы:

771

Для всех стандартных типов библиотек функция-член empty()является запросом, а не командой, то есть она означает "ты пустой?" не "пожалуйста, выбросьте свое содержимое".

Функция- clear()член наследуется от iosи используется для очистки состояния ошибки потока, например, если файловый поток имеет состояние ошибки, установленное в eofbit(конец файла), то при вызове clear()будет возвращено состояние ошибки goodbit(без ошибок) ,

Для очистки содержимого stringstream, используя:

m.str("");

правильно, хотя с использованием:

m.str(std::string());

технически более эффективен, потому что вы избегаете вызова std::stringконструктора, который принимает const char*. Но любой компилятор в наши дни должен иметь возможность генерировать один и тот же код в обоих случаях - так что я бы просто пошел с тем, что более читабельно.

Wilka
источник
105
Вот что происходит, когда вы забываете часть «clear ()». stackoverflow.com/q/2848087/635549
Галат
8
@KshitijBanerjee Я думаю, что в C ++ m.str () и m.str ("") - две разные функции. m.str () вызывает функцию, которая не ожидала какого-либо параметра, тогда как m.str ("") вызывает функцию, которая принимает параметр const char *. m.str () мог быть реализован как функция get, которая возвращает строку, тогда как m.str ("") мог быть реализован как функция set .
Динеш пиар
4
Как сказал Галат, очень важно также добавить m.clear (); в дополнение к m.str ("") ;. В противном случае вы можете получить проблемы, если в какой-то момент вы заполните поток строк пустой строкой.
Спутник
1
@anthropod Да, это было в прошлом году. С тех пор я получил это работает.
Джеймс
1
О, мальчик, это интуитивно понятно. Как и все остальное в C ++!
солнечная луна
47

Вы можете очистить состояние ошибки и очистить поток строк в одну строку

std::stringstream().swap(m); // swap m with a default constructed stringstream

Это эффективно сбрасывает m в состояние по умолчанию

Никос Атанасиу
источник
3
Это самый эффективный и самый элегантный способ сделать это по сравнению со всеми другими ответами здесь. Однако std :: stringstream :: swap является функцией c ++ 11, и это решение не работает для предыдущих компиляторов c ++ 11.
101010
4
Функция по- прежнему отсутствует в GNU г ++ v4.8 см stackoverflow.com/questions/24429441/...
Joachim W
7
@ 101010: Как обмен лучше, чем перемещение?
Дедупликатор
2
@ AsetD: Даже если это не исключение, вы забыли временное построение по умолчанию?
дедупликатор
3
Это малоэффективно. Когда я хочу повторно использовать оригинальные сс. Это меняет пустое место для меня.
Чжан
36
m.str("");

похоже на работу.

CodingWithoutComments
источник
3
Это будет очищено с помощью .clear (), который указан в OP.
Дейв Лугг
33

Это должно быть самым надежным способом независимо от компилятора:

m=std::stringstream();
jerron
источник
2
На мой взгляд, это лучше, потому что m.str (""); заставил мой поток строк зависнуть с этим пустым значением, что бы я ни пытался. Но, используя это, у меня нет этой проблемы
желатин1
3
Я столкнулся с той же проблемой, для меня mm.clear(); mm.str("");сделали свое дело. (нет C ++ 11, иначе обмен был бы лучше).
hochl
1
@hochl: Почему это swapлучше, чем задание на переезд?
Дедупликатор
4
Это не хорошо для всех ситуаций. Это будет перераспределять буфер каждый раз, а mm.str ("") - нет.
Шиталь Шах
3
Мой основной вариант использования для сброса объекта stringstream заключается в сохранении потокового локального объекта stringstream для предотвращения ненужного создания экземпляра stringstream - создание экземпляра нового объекта stringstream копирует глобальный объект языкового стандарта - теоретически это быстро и требует только увеличения атомарного значения, но на уровне параллелизма я имею дело с тем, что он часто наносит вред.
Spacemoose
12

Я всегда смотрю на это:

{
    std::stringstream ss;
    ss << "what";
}

{
    std::stringstream ss;
    ss << "the";
}

{
    std::stringstream ss;
    ss << "heck";
}
Тимок
источник
1
Это лучше, чем очисткаstringstream?
Robur_131
11

мои 2 цента:

мне показалось, что это работает для меня в xcode и dev-c ++, у меня была программа в форме меню, которое при многократном выполнении по запросу пользователя будет заполнять переменную stringstream, которая будет нормально работать в первый раз, когда код выполнить, но не очистит поток строк в следующий раз, когда пользователь запустит тот же код. но две строки кода ниже, наконец, очищают переменную stringstream каждый раз перед заполнением строковой переменной. (2 часа проб и ошибок и поиск в Google), между прочим, использование каждой строки самостоятельно не поможет.

//clear the stringstream variable

sstm.str("");
sstm.clear();

//fill up the streamstream variable
sstm << "crap" << "morecrap";
Франсиско Кортес
источник
-1

Это концептуальная проблема.

Stringstream является потоком, поэтому его итераторы являются прямыми и не могут возвращаться. В выходном потоке строк вам потребуется flush () для его повторной инициализации, как и в любом другом выходном потоке.

Алчино Далл Игна Младший
источник
2
ru.cppreference.com/w/cpp/io/basic_ostream/flush flush синхронизируется с устройством хранения, с которым оно связано. Это не та же самая реинициализация.
уточнение
-12

Они не отбрасывают данные в потоке строк в gnu c ++

    m.str("");
    m.str() = "";
    m.str(std::string());

Следующее очищает поток строк для меня:

    m.str().clear();
Джон
источник
7
Я не уверен, что это сработает, по тем же причинам, по которым Бернхардруш не сработает. Функция .str () возвращает копию, и очистка копии ничего не сделает.
Verdagon
1
Это решение НЕ работает для Microsoft Visual C ++.
Зак
Неправильно. Clear будет работать со строкой, возвращаемой из потока, а не с самим потоком.
Джои Карсон