2012-07-12 10 views
9

he el siguiente código:Problema con cin cuando se introducen espacios, usando clase string

main.cpp

#include <iostream> 
#include <string> 

using namespace std; 

string name; 
string age; 

int main() { 
    cout <<"Name: "; 
    cin >> name; 
    cout << endl; 
    cout <<"Age: "; 
    cin >> age; 
    cout << endl; 
    cout << "Your name is " << name << ", and you are " << age << " years old." << endl; 
    cout << "Press enter to close this application" << endl; 
    getchar(); 
    return 0; 
} 

me di cuenta de que si pongo un espacio en mi entrada para el nombre que ganó No tengo la oportunidad de ingresar el nombre, y verá la entrada después del espacio como la edad. Me disculpo si este es un error de principiante, que probablemente sea. Anteriormente programé Java y decidí que quería cambiar a C++ porque se adapta mejor a mis necesidades. También es probable que formatee mi código de manera extraña según sus estándares, corríjalo si lo desea.

Screenshot of console

También he notado otro error, algo que en realidad nunca tuve ningún problema con Java. No puedo entender cómo evitar que se cierre al instante cuando finaliza el procesamiento. He oído que puedes usar "system. (" Pause "), pero también me han dicho que no lo use. Realmente estoy confundido sobre qué usar. He oído usar getchar() ;, pero no parece hacer nada.

Cualquier ayuda sería muy apreciada, ya que soy un principiante cuando se trata de C++.

+0

@chris Me gustaría elegir su comentario como respuesta, pero realmente no creo que me lo permita. Gracias por tu ayuda. ¿Te importaría volver a publicar eso o algo como respuesta para poder seleccionarlo? –

+0

Antes de su comentario, decidí hacer una respuesta más detallada. Está allí (y afortunadamente no tiene errores sutiles) si quieres leerlo. – chris

+0

Ah, y la razón por la que su 'getchar' no funciona es la misma razón por la que mi primer ejemplo para reemplazar' system ("pause") 'no funciona. Se explica en la respuesta. – chris

Respuesta

13

Esto es lo que está pasando con el buffer de entrada al ejecutar programa:

std::cin >> name; 

Usted está esperando la respuesta. Cuando se introduce "Ryan Cleary", y pulse ENTER, el búfer de entrada contiene:

Ryan Cleary\n 

Ahora su cin lee la entrada de forma normal, con parada en los espacios en blanco, dejando el búfer de esta manera:

Cleary\n 

Nota el espacio inicial, ya que se detiene después de leer Ryan. Su primera variable ahora contiene Ryan. Sin embargo, si desea el nombre completo, use std::getline. Leerá hasta una línea nueva, no solo espacios en blanco. De todos modos, continuando:

std::cin >> age; 

Ahora está recibiendo otra entrada. Sin embargo, ya hay algo allí. Se salta el espacio en blanco hasta que se pueda iniciar la lectura, dejando la memoria intermedia con sólo:

\n 

Su segunda variable obtiene el texto Cleary. Tenga en cuenta la nueva línea todavía en el búfer, lo que me lleva a la segunda parte. Reemplazar system ("pause"); de una manera que siempre funciona es complicado.Su mejor apuesta es por lo general a vivir con una solución menos-que-perfecta, o como me gusta hacer, uno que no está garantizado para hacer exactamente lo que dice:

std::cin.get(); //this consumes the left over newline and exits without waiting 

bien, así que no lo hicieron cin.get() trabajo. ¿Qué tal esto:

std::cin.get(); //consume left over newline 
std::cin.get(); //wait 

Eso funciona perfectamente, pero ¿y si lo copias y lo pegas en algún lugar donde la nueva línea no sobra? ¡Tendrás que presionar enter dos veces!

La solución es borrar la nueva línea (y cualquier otra cosa) y esperar. Este es el propósito de cin.sync(). Sin embargo, como se ve en la sección de notas, no está garantizado borrar el búfer como dice, por lo que si el compilador elige no hacerlo, no se puede usar. Para mí, sin embargo, hace exactamente eso, dejando una solución de:

std::cin.sync(); //clear buffer 
std::cin.get(); //wait 

Lo principal mal por system("pause"); es que usted no tiene idea de qué programa se ejecutará en el ordenador de alguien. Podrían haber cambiado pause.exe o poner uno que se encuentra primero, y no tienes forma de saberlo. Esto podría potencialmente arruinar su computadora debido a que posiblemente sea cualquier programa.

+1

Gracias, una excelente respuesta. Me explicó mucho. Tengo mucha más comprensión que antes con la forma en que C++ analiza la entrada. –

+0

Me encontré con esto mientras buscaba en Google. Una excelente explicación Gracias v. Mucho. – PingPing

7

Usted debe tratar cin.getline, de esa manera, la corriente será leer hasta el primer carácter de nueva línea.

Ok, malos consejos ya que algunas personas señalaron. puede utilizar std::getline para leer una línea entera. una vez más, el delimitador es el salto de línea, a no ser informado. para leer desde cin, puede pasarlo como el primer parámetro (y la cadena como el segundo).

std::string str; 
std::getline(cin, str); // to read until the end of line 

std::getline(cin, str, ' '); // to read until a space character, for instance 

(por supuesto, se puede omitir la parte std:: de las líneas, ya que ya informado al compilador que está utilizando el std espacio de nombres)

+0

-1 mal consejo. 'std :: getline' es seguro y fácil,' cin.getline' no lo es. –

+0

Me perdí la parte donde OP dijo que estaba usando la clase de cuerda. –

+0

Corregido. Pero de todos modos, no merezco votaciones porque pido prestada la respuesta de los comentarios ... –

Cuestiones relacionadas