Як очистити змінну струну?


Відповіді:


771

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

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

Для очищення вмісту а stringstreamвикористовуйте:

m.str("");

є правильним, хоча використовує:

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

технічно ефективніше, тому що ви уникаєте посилань на std::stringконструктор, який займає const char*. Але будь-який компілятор в ці дні повинен мати можливість генерувати один і той же код в обох випадках - тому я б просто зайнявся тим, що можна прочитати.


105
Ось що відбувається, коли ви забудете частину "clear ()". stackoverflow.com/q/2848087/635549
galath

8
@KshitijBanerjee Я думаю, що в C ++ m.str () і m.str ("") є дві різні функції. m.str () викликає функцію, яка не очікувала жодного параметра, тоді як m.str ("") викликає функцію, яка приймає параметр const char *. m.str (), можливо, була реалізована як функція get, яка повертає рядок, тоді як m.str ("") може бути реалізований як набір функцій.
Дінеш PR

4
Як сказав галат, дуже важливо також додати m.clear (); крім m.str ("") ;. Інакше у вас можуть виникнути проблеми, якщо в якийсь момент ви заповните потоковий рядок порожнім рядком.
Sputnik

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 g ++ v4.8, див. Stackoverflow.com/questions/24429441/…
Йоахім В

7
@ 101010: Як заміни краще, ніж переміщення-призначення?
Дедуплікатор

2
@AsetD: Навіть якщо це виняток, ви забули тимчасово створені за замовчуванням?
Дедуплікатор

3
Це малоефективно. Коли я хочу використати оригінальний ss. Він міняє порожнє для мене.
Чжан


33

Це має бути найнадійнішим способом незалежно від компілятора:

m=std::stringstream();

2
На мій погляд, це краще, тому що m.str (""); змусив мій стринг-стрийт з цим порожнім значенням, що б я не намагався. Але використовуючи це, у мене немає такої проблеми
gelatine1

3
Я зіткнувся з тією ж проблемою, для мене mm.clear(); mm.str("");зробив трюк. (немає C ++ 11, інакше підміна буде краще).
hochl

1
@hochl: Чому було swapб краще, ніж переміщення-призначення?
Дедуплікатор

4
Це не добре для всіх ситуацій. Це буде перерозподіляти буфер кожного разу, поки mm.str ("") не буде.
Shital Shah

3
Моїм основним випадком використання для промивання об'єкта stringstream є збереження ниткоподібного об'єкта stringstream навколо, щоб запобігти непотрібному екземпляру stringstream - інстанціювання нового об'єкта stringstream копіює глобальний локальний об'єкт - теоретично це швидко і передбачає лише збільшення атомного, але на рівні одночасності, з якою я маю справу, це часто калічить.
Spacemoose

12

Я завжди обмірковую це:

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

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

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

Це краще, ніж очищення stringstream?
Robur_131

11

мої 2 копійки:

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

//clear the stringstream variable

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

//fill up the streamstream variable
sstm << "crap" << "morecrap";

-1

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

Stringstream - це потік, тому його ітератори вперед, не можуть повернутися. У вихідному потоковому потоці вам потрібен flush () для його повторної ініціалізації, як і в будь-якому іншому потоці виводу.


1
en.cppreference.com/w/cpp/io/basic_ostream/flush флеш синхронізується із пристроєм зберігання даних, з яким він пов'язаний. Це не та ж реініціалізація.
Ясна

-11

Вони не відкидають дані у потоці рядків у gnu c ++

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

Далі випорожнюється потоковий рядок для мене:

    m.str().clear();

7
Я не дуже впевнений, що це спрацює, тому що з тих же причин Бернгардш не працював. Функція .str () повертає копію, і очищення копії нічого не призведе.
Вердагон

1
Це рішення НЕ працює для Microsoft Visual C ++.
Зак

Неправильно. Очистити буде функціонувати над рядком, поверненим із потоку, а не самим потоком.
Джої Карсон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.