Que fait exactement stringstream?

J'essaie d'apprendre le C++ depuis hier et j'utilise ce document: http://www.cplusplus.com/files/tutorial.pdf (page 32). J'ai trouvé un code dans le document et je l'ai exécuté. J'ai essayé d'entrer Rs 5.5 pour le prix et un entier pour la quantité et la sortie était 0. J'ai essayé d'entrer 5.5 et 6 et la sortie était correcte.

// stringstreams
#include <iostream> 
#include <string> 
#include <sstream> 

using namespace std; 

int main () 
{ 
  string mystr; 
  float price = 0; 
  int quantity = 0; 

  cout << "Enter price: "; 
  getline (cin,mystr); 
  stringstream(mystr) >> price; 
  cout << "Enter quantity: "; 
  getline (cin,mystr); 
  stringstream(mystr) >> quantity; 
  cout << "Total price: " << price*quantity << endl; 
  return 0; 
}

Question: Que fait exactement la commande mystring? Citation du document:

" dans cet exemple, nous acquérons des valeurs numériques l'entrée standard indirectement. Au lieu d'extraire des valeurs numériques directement entrée standard, Nous obtenons des lignes de l'entrée standard (cin) dans un string object (mystr), puis nous extrayons les valeurs entières de cette chaîne dans une variable de type int (quantité)."

Mon impression était que la fonction prendra la partie intégrante d'une chaîne et l'utilisera comme entrée.

(je ne sais pas exactement comment poser une question ici. Je suis également nouveau à la programmation) Merci vous.

77
c++
demandé sur Martin G 2013-12-15 16:31:08

4 réponses

Parfois, il est très pratique d'utiliser stringstream pour convertir entre des chaînes et d'autres types numériques. L'utilisation de stringstream est similaire à l'utilisation de iostream, de sorte qu'il n'est pas un fardeau pour apprendre.

Les Stringstreams peuvent être utilisés pour lire des chaînes et écrire des données dans des chaînes. Il fonctionne principalement avec un tampon de chaîne, mais sans un vrai canal d'E/S.

Les fonctions membres de base de la classe stringstream sont

  • str(), qui renvoie le contenu de son tampon dans type de chaîne.

  • str(string), qui définit le contenu du tampon sur l'argument string.

Voici un exemple d'utilisation des flux de chaînes.

ostringstream os;
os << "dec: " << 15 << " hex: " << std::hex << 15 << endl;
cout << os.str() << endl;

Le résultat est dec: 15 hex: f.

istringstream est plus ou moins la même utilisation.

Pour résumer, stringstream est un moyen pratique de manipuler des chaînes comme un périphérique d'E/S indépendant.

POUR INFO, les relations d'héritage entre les classes sont:

classes de flux de chaîne

128
répondu richard.g 2018-03-15 15:55:30

Pour répondre à la question. stringstream vous permet essentiellement de traiter un objet string comme un stream, et d'utiliser toutes les fonctions et tous les opérateurs stream.

Je l'ai vu utilisé principalement pour la qualité de sortie/entrée formatée.

Un bon exemple serait c++ implémentation de la conversion de number en objet stream.

Exemple Possible:

template <class T>
string num2str(const T& num, unsigned int prec = 12) {
    string ret;
    stringstream ss;
    ios_base::fmtflags ff = ss.flags();
    ff |= ios_base::floatfield;
    ff |= ios_base::fixed;
    ss.flags(ff);
    ss.precision(prec);
    ss << num;
    ret = ss.str();
    return ret;
};

C'est Peut-être un peu compliqué mais c'est assez complexe. Vous créez stringstream object ss, modifiez ses drapeaux, y mettez un nombre avec operator<<, et l'extraire via str(). Je suppose que operator>> pourrait être utilisé.

Dans cet exemple, le tampon string est masqué et n'est pas utilisé explicitement. Mais il serait trop long d'écrire sur tous les aspects et cas d'utilisation possibles.

Note: je l'ai probablement volé à quelqu'un sur SO et raffiné, mais je n'ai pas d'auteur original noté.

15
répondu luk32 2013-12-15 12:52:20

À Partir De C++ Primer:

Le istringstream type de lit - string, ostringstream écrit un string, et stringstream lit et écrit les string.

Je rencontre certains cas où il est à la fois pratique et concis d'utiliser stringstream.

Cas 1

, Il est de l'une des solutions pour cette leetcode problème. Il démontre un très approprié cas où l'utilisation de stringstream est efficace et concis.

Supposons que a et b sont des nombres complexes exprimés au format chaîne, nous voulons obtenir le résultat de la multiplication de a et b également au format chaîne. Le code est le suivant:

string a = "1+2i", b = "1+3i";
istringstream sa(a), sb(b);
ostringstream out;

int ra, ia, rb, ib;
char buff;
// only read integer values to get the real and imaginary part of 
// of the original complex number
sa >> ra >> buff >> ia >> buff;
sb >> rb >> buff >> ib >> buff;

out << ra*rb-ia*ib << '+' << ra*ib+ia*rb << 'i';

// final result in string format
string result = out.str() 

Cas 2

C'est aussi à partir d'un problème leetcode {[34] } qui vous oblige à simplifier la chaîne de chemin donnée, l'une des solutions utilisant stringstream est la plus élégante que j'ai voir:

string simplifyPath(string path) {
    string res, tmp;
    vector<string> stk;
    stringstream ss(path);
    while(getline(ss,tmp,'/')) {
        if (tmp == "" or tmp == ".") continue;
        if (tmp == ".." and !stk.empty()) stk.pop_back();
        else if (tmp != "..") stk.push_back(tmp);
    }
    for(auto str : stk) res += "/"+str;
    return res.empty() ? "/" : res; 
 }

Sans l'utilisation de stringstream, il serait difficile d'écrire un code aussi concis.

12
répondu jdhao 2017-09-18 07:21:46

Vous avez entré un caractère alphanumérique et int, délimité en blanc dans mystr.

Vous avez ensuite essayé de convertir le premier jeton (délimité en blanc) en int.

Le premier jeton était RS qui n'a pas réussi à convertir en int, laissant un zéro pour myprice, et nous savons tous ce que zéro fois quoi que ce soit rapporte.

Lorsque vous n'avez entré des valeurs int que la deuxième fois, tout a fonctionné comme prévu.

C'est le faux RS qui a causé l'échec de votre code.

2
répondu ilocos joe 2015-08-11 09:05:13