Pregunta ¿Qué hace exactamente stringstream?


Estoy tratando de aprender C ++ desde ayer y estoy usando este documento:http://www.cplusplus.com/files/tutorial.pdf (página 32). Encontré un código en el documento y lo ejecuté. Intenté ingresar Rs 5.5 por precio y un entero por cantidad y la salida fue 0. Intenté ingresar 5.5 y 6 y la salida fue correcta.

// 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; 
}

Pregunta: ¿Qué hace exactamente el comando mystring? Citando del documento:

"En este ejemplo, adquirimos valores numéricos de la entrada estándar   indirectamente. En lugar de extraer valores numéricos directamente del   entrada estándar, obtenemos líneas de la entrada estándar (cin) en una   string object (mystr), y luego extraemos los valores enteros de   esta cadena en una variable de tipo int (cantidad) ".

Mi impresión fue que la función tomará la parte integral de una cadena y la usará como entrada.

(No sé exactamente cómo hacer una pregunta aquí. También soy nuevo en la programación) Gracias.


76
2017-12-15 12:31


origen


Respuestas:


Algunas veces es muy conveniente usar stringstream para convertir cadenas y otros tipos numéricos. El uso de stringstream es similar al uso de iostream, entonces no es una carga aprender.

Stringstreams se puede usar tanto para leer cadenas como para escribir datos en cadenas. Funciona principalmente con un búfer de cadenas, pero sin un canal real de E / S.

Las funciones básicas de miembros de la clase stringstream son

  • str(), que devuelve el contenido de su búfer en tipo de cadena.

  • str(string), que establece el contenido del búfer en el argumento de cadena.

Aquí hay un ejemplo de cómo usar cadenas de transmisión.

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

El resultado es dec: 15 hex: f.

istringstream es de más o menos el mismo uso.

Para resumir, stringstream es una forma conveniente de manipular cadenas como un dispositivo de E / S independiente.

FYI, las relaciones de herencia entre las clases son:

string stream classes


119
2017-12-15 13:28



Para responder la pregunta. stringstream básicamente te permite tratar un string objeto como un streamy usa todo stream funciones y operadores en él.

Lo vi utilizado principalmente para la bondad de salida / entrada formateada.

Un buen ejemplo sería c++ implementación del número de conversión a objeto de flujo.

Posible ejemplo:

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;
};

Tal vez es un poco complicado, pero es bastante complejo. Tu creas stringstream objeto ss, modifica sus banderas, ponle un número con operator<<y extraerlo a través de str(). Supongo operator>> puede ser usado.

También en este ejemplo, string el búfer está oculto y no se usa explícitamente. Pero sería una publicación demasiado larga para escribir sobre cada aspecto posible y caso de uso.

Nota: Probablemente se lo robé a alguien con SO y refinado, pero no tengo un autor original anotado.


15
2017-12-15 12:47



De C ++ Primer:

los istringstream tipo lee un cuerda, ostringstream escribe un cuerday cadena lee y escribe el cuerda.

Me encuentro con algunos casos donde es conveniente y conciso para usar cadena.

caso 1

Es de una de las soluciones para este problema de leetcode. Demuestra un caso muy adecuado donde el uso de cadena es eficiente y conciso.

Suponer a y b son números complejos expresados ​​en formato de cadena, queremos obtener el resultado de la multiplicación de a y b también en formato de cadena. El código es el siguiente:

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() 

caso 2

También es de una problema de leetcode eso requiere que simplifiques la cadena de ruta dada, una de las soluciones usando stringstream es el más elegante que he visto:

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; 
 }

Sin el uso de stringstream, sería difícil escribir un código tan conciso.


12
2018-06-27 14:22



Usted ingresó un alfanumérico e int, en blanco delimitado en mystr.

Luego trataste de convertir el primer token (delimitado en blanco) en un int.

El primer token fue RS que no se pudo convertir a int, dejando un cero para mi precio, y todos sabemos qué rinde cero cero.

Cuando solo ingresó valores int la segunda vez, todo funcionó como esperaba.

Fue el RS espurio el que causó que tu código fallara.


2
2017-08-11 02:09