2010-01-27 9 views
9

Estoy tratando de utilizar las prácticas de seguridad en el manejo de entrada con los números sólo en C++, por lo que utilizar un objeto stringstream como tan:Problema con la reutilización de un objeto stringstream

#include <iostream> 
#include <string> 
#include <sstream> 
using namespace std; 

int main() 
{ 
    int first, second; 
    string input; 

    stringstream sstream; 

    cout << "First integer: "; 
    getline(cin, input); 
    sstream.str(input); 
    sstream >> first; 

    cout << first << endl; //display user input in integers 

    cout << "Second integer: "; 
    getline(cin, input); 
    sstream.str(input); 
    sstream >> second; 

    cout << second << endl; //display user input in integers 

    getline(cin, input); //pause program 

    return 0; 
} 

Sin embargo, la segunda vez parece darle a la variable 'segundo' un valor arbitrario. Esta es la salida:

First integer: 1 
1 
Second integer: 2 
2293592 

Si Declaro dos objetos stringstream y los utilizan, respectivamente, para las dos variables parece que funciona bien. ¿Esto significa que no puedo volver a utilizar un objeto de cadena de caracteres de la forma en que estoy tratando de hacerlo? En mi programa real, tengo la intención de manejar mucho más que dos valores de entrada del usuario, así que solo quiero asegurarme de que haya otra forma en lugar de crear múltiples objetos de secuencia de cadenas. Dudo que sea de gran relevancia, pero estoy en Windows XP y estoy usando MinGW como mi compilador.

Agradeceré cualquier ayuda.

Respuesta

13

Utilice sstream.clear(); después de sstream >> first;.

+1

Justo lo que estaba buscando Por. Me encantan las respuestas rápidas en este sitio. – kaykun

4

Una mejor forma de hacer esta conversión entre los tipos de datos sería usar boost::lexical_cast.

La información y los ejemplos se pueden encontrar en el Boost Site.

A continuación se muestra un ejemplo de hacer una int a la conversión de cadena y viceversa (cadena a int) como lo que está haciendo en su programa.

#include <string> 
#include <boost/lexcal_cast.hpp> 

int main(int argc, char *argv[]) 
{ 
    int i = 42; 
    std::string s = boost::lexical_cast<std::string>(i); 
    int j = boost::lexical_cast<int>(s); 

    return 1; 
} 
+1

O, si el OP no quiere usar Boost, puede escribir su propio elenco léxico en aproximadamente cinco líneas de código (véase http://www.gotw.ca/ publicaciones/mill19.htm) –

2
cout << "First integer: "; 
getline(cin, input); 
sstream.str(input); 
sstream >> first;  // state of sstream may be eof 

cout << "Second integer: "; 
getline(cin, input); 
sstream.str(input); 
sstream.clear();  // clear eof state 
sstream >> second; // input from sstream 
11

tendrá que restablecer el estado de la stringstream. Generalmente, esto implica dos pasos: borrar la memoria:

sstream.str(""); 

y reactivación, los indicadores del estado de error:

sstream.clear(); 

Si no se borre la memoria intermedia, si se obtiene una entrada como "123abc" luego, "abc" seguirá en la transmisión cuando intente leer la próxima vez.

También debe asegurarse de probar el estado de falla de la secuencia (sstream.fail()) para asegurarse de que la extracción fue exitosa. Si desea asegurarse de que el usuario ingresó un número entero (es decir, desea evitar que el usuario ingrese, digamos, "123abc", entonces debe verificar que sstream.eof() sea verdadero.

Cuestiones relacionadas