Comment effacez-vous une variable stringstream?


Réponses:


771

Pour tous les types de bibliothèques standard, la fonction membre empty()est une requête, pas une commande, c'est-à-dire qu'elle signifie "êtes-vous vide?" pas "veuillez jeter votre contenu".

La clear()fonction membre est héritée de ioset est utilisée pour effacer l'état d'erreur du flux, par exemple si un flux de fichiers a l'état d'erreur défini sur eofbit(fin de fichier), alors l'appel clear()rétablira l'état d'erreur sur goodbit(pas d'erreur) .

Pour effacer le contenu d'un stringstream, en utilisant:

m.str("");

est correct, bien qu'en utilisant:

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

est techniquement plus efficace, car vous évitez d'appeler le std::stringconstructeur qui prend const char*. Mais n'importe quel compilateur de nos jours devrait être capable de générer le même code dans les deux cas - je choisirais donc tout ce qui est plus lisible.


105
Voici ce qui se passe lorsque vous oubliez la partie "clear ()". stackoverflow.com/q/2848087/635549
galath

8
@KshitijBanerjee Je pense qu'en C ++ m.str () et m.str ("") sont deux fonctions différentes. m.str () invoque une fonction qui n'attendait aucun paramètre tandis que m.str ("") invoque la fonction qui accepte un paramètre const char *. m.str () peut avoir été implémenté comme une fonction get qui retourne la chaîne alors que m.str ("") peut avoir été implémenté comme une fonction set .
Dinesh PR

4
Comme l'a dit galath, il est également très important d'ajouter m.clear (); en plus de m.str ("") ;. Sinon, vous pouvez rencontrer des problèmes si, à un moment donné, vous remplissez le flux de chaînes avec une chaîne vide.
Sputnik

1
@anthropod Oui, c'était l'année dernière. Je l'ai depuis fait fonctionner.
James

1
Oh boy est-ce intuitif. Comme tout le reste sur C ++!
lune ensoleillée

47

Vous pouvez effacer l'état d'erreur et vider le train de chaînes sur une seule ligne

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

Cela réinitialise effectivement m à un état construit par défaut


3
C'est la façon la plus efficace et la plus élégante de le faire par rapport à toutes les autres réponses ici. Cependant, std :: stringstream :: swap est une fonctionnalité c ++ 11 et cette solution ne fonctionne pas pour les compilateurs c ++ 11 antérieurs.
101010

4
Fonctionnalité toujours manquante dans GNU g ++ v4.8, voir stackoverflow.com/questions/24429441/…
Joachim W

7
@ 101010: En quoi l'échange est-il meilleur que l'affectation de déplacement?
Déduplicateur

2
@AsetD: Même si ce n'est pas le cas, avez-vous oublié le temporaire construit par défaut?
Déduplicateur

3
C'est peu efficace. Quand je veux réutiliser les ss originaux. Il échange un vide pour moi.
Zhang


33

Cela devrait être le moyen le plus fiable quel que soit le compilateur:

m=std::stringstream();

2
C'est mieux à mon avis parce que m.str (""); fait que mon flux de chaînes soit bloqué avec cette valeur vide quoi que j'aie essayé. Mais en utilisant cela, je n'ai pas ce problème
gelatine1

3
J'ai rencontré le même problème, car j'ai mm.clear(); mm.str("");fait l'affaire. (pas de C ++ 11, sinon le swap serait mieux).
hochl

1
@hochl: Pourquoi serait- swapil préférable à l'affectation de mouvement?
Déduplicateur

4
Ce n'est pas bon pour toutes les situations. Cela réallouerait le tampon à chaque fois, contrairement à mm.str ("").
Shital Shah

3
Mon principal cas d'utilisation pour vider un objet de chaîne de caractères consiste à conserver un objet de chaîne de caractères local pour éviter toute instanciation inutile de la chaîne de caractères - l'instanciation d'un nouvel objet de chaîne de caractères copie l'objet global global - en théorie, cela est rapide et implique uniquement l'incrémentation d'un atomique, mais au niveau de la simultanéité avec laquelle je traite, c'est souvent paralysant.
Spacemoose

12

Je suis toujours en train de l'étudier:

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

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

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

1
Est-ce mieux que d'effacer lestringstream?
Robur_131

11

mes 2 cents:

cela semblait fonctionner pour moi dans xcode et dev-c ++, j'avais un programme sous la forme d'un menu qui, s'il était exécuté de manière itérative à la demande d'un utilisateur, remplirait une variable stringstream qui fonctionnerait bien la première fois que le code le ferait exécuter mais n'effacera pas le flux de chaînes la prochaine fois que l'utilisateur exécutera le même code. mais les deux lignes de code ci-dessous ont finalement effacé la variable stringstream à chaque fois avant de remplir la variable string. (2 heures d'essais et d'erreurs et de recherches Google), btw, utiliser chaque ligne seule ne ferait pas l'affaire.

//clear the stringstream variable

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

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

-1

C'est un problème conceptuel.

Stringstream est un flux, donc ses itérateurs sont en avant, ne peuvent pas retourner. Dans un flux de chaîne de sortie, vous avez besoin d'un flush () pour le réinitialiser, comme dans tout autre flux de sortie.


2
en.cppreference.com/w/cpp/io/basic_ostream/flush flush se synchronise avec le périphérique de stockage auquel il est associé. Ce n'est pas la même réinitialisation.
Plus clair

-12

Ceux-ci ne suppriment pas les données dans le flux de chaînes dans gnu c ++

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

Ce qui suit vide le string pour moi:

    m.str().clear();

7
Je ne suis pas sûr que cela fonctionnerait, pour les mêmes raisons que bernhardrusch ne fonctionnerait pas. La fonction .str () renvoie une copie, et l'effacement de la copie ne ferait rien.
Verdagon

1
Cette solution ne fonctionne PAS pour Microsoft Visual C ++.
Zak

Incorrect. Clear fonctionnerait sur la chaîne renvoyée par le flux, pas sur le flux lui-même.
Joey Carson
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.