web-dev-qa-db-fra.com

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é de saisir Rs 5.5 pour le prix et un entier pour la quantité et la sortie était égale à 0. J'ai essayé de saisir 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 indirectement les valeurs numériques de l'entrée standard. Au lieu d'extraire directement les valeurs numériques de l'entrée standard, nous obtenons des lignes de l'entrée standard (cin) dans un objet chaîne (mystr), puis nous extrayons l'entier les valeurs de cette chaîne dans une variable de type int (quantité). "

Mon impression était que la fonction prendrait la partie intégrale d'une chaîne et l'utiliserait comme entrée.

(Je ne sais pas exactement comment poser une question ici. Je suis également novice en programmation) Merci.

88
user3104350

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

Les chaînes de caractères peuvent être utilisées à la fois pour lire des chaînes et pour écrire des données dans des chaînes. Il fonctionne principalement avec un tampon de chaîne, mais sans véritable canal d'E/S.

Les fonctions membres de base de la classe stringstream sont

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

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

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

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

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

istringstream a plus ou moins le même usage.

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

Pour votre information, les relations d'héritage entre les classes sont:

string stream classes

153
richard.g

Pour répondre à la question. stringstream vous permet fondamentalement 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é sortie/entrée formatée.

Un bon exemple serait c++ implémentation de la conversion de nombre 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 objet ss, modifiez ses drapeaux, y mettez un numéro avec operator<< et extrayez-le via str(). Je suppose que operator>> pourrait être utilisé.

De plus, 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 les cas d’utilisation possibles.

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

18
luk32

De C++ Primer :

Le type istringstream lit une chaîne , ostringstream écrit une chaîne et stringstream lit et écrit le chaîne .

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

cas 1

C'est à partir de ne des solutions pour ce problème de code de calcul . Cela démontre un cas très approprié où l'utilisation de stringstream est efficace et concise.

Supposons que a et b soient 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 comme suit:

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 un problème de code de code qui vous oblige à simplifier la chaîne de chemin donnée, l'une des solutions utilisant stringstream est le plus élégant que j'ai vu:

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.

16
jdhao

Vous avez entré des caractères alphanumériques et int, vierges délimités dans mystr.

Vous avez ensuite essayé de convertir le premier jeton (délimité par des blancs) en un int.

Le premier jeton était RS, qui n'a pas réussi à convertir en int, laissant un zéro pour mon prix, et nous savons tous à quel zéro tout rapporterait.

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

C'est le RS parasite qui a provoqué l'échec de votre code.

2
ilocos joe