std :: entrada cin con espacios?

144
#include <string>

std::string input;
std::cin >> input;

El usuario quiere ingresar "Hello World". Pero cinfalla en el espacio entre las dos palabras. ¿Cómo puedo hacer una cintoma de todo Hello World?

De hecho, estoy haciendo esto con estructuras y cin.getlineno parece funcionar. Aquí está mi código:

struct cd
{
    std::string CDTitle[50];
    std::string Artist[50];
    int number_of_songs[50];
};

std::cin.getline(library.number_of_songs[libNumber], 250);

Esto produce un error. ¿Algunas ideas?

limón
fuente
27
No debe editar sus preguntas para hacer nuevas preguntas como esa. La razón es que la gente ya ha dado respuestas a su pregunta original y ahora esas respuestas parecen estar fuera de contexto. Si su pregunta original ya ha sido respondida, simplemente comience una nueva pregunta para evitar confusiones.
Pete
Es evidente después de un poco de examen, pero ¿podría añadir una declaración de la variable librarypor lo que es claro que es del tipocd
chandsie
lo siento chicos, esto se hizo a toda prisa, volveré a publicar esto.
limón
1
Si va a volver a publicarlo a modo de reemplazo, marque la pregunta para su eliminación por un mod.
ligereza corre en órbita el
2
En su actualización, está intentando getlineingresar a un int. Por supuesto que falla.
Ben Voigt

Respuestas:

102

Tienes que usar cin.getline():

char input[100];
cin.getline(input,sizeof(input));
Pete
fuente
77
@ Kevin Meh, sucede. C ++ no es exactamente tan intuitivo como nos gustaría que fuera.
Pete
61
Ew; ¿Por qué usar char-buffers? Es 2011.
ligereza corre en órbita el
3
¿Y por qué no usar cin.getline(input, sizeof(input));? Además, ¿no debería verificar el estado de devolución?
Jonathan Leffler
2
@JonathanLeffler En el momento en que esto se escribió, esta era la respuesta que tenía para la pregunta que se hizo originalmente (mire el primer comentario para la pregunta real y verá que el contexto ha cambiado debido a una edición por parte del OP). De cualquier manera, si siente que la respuesta es tan terrible, desestime el voto. Reconozco que esta puede no ser la "mejor" solución, pero no es menos una solución. En lugar de preguntar por qué no usé algo, podría decirnos a todos por qué deberíamos hacerlo a su manera.
Pete
77
Su respuesta no es terrible y no necesita voto negativo. Creo que dos pequeños cambios lo mejorarían. El cambio 1 se usaría sizeof(input)en lugar de 100 en la llamada a cin.getline(); eso significaría que puede cambiar el tamaño del búfer de entrada y solo necesita cambiar una línea en lugar de dos líneas. El cambio 2 sería probar el retorno cin.getline()utilizando, por ejemplo, if (!cin.getline(input, sizeof(input))) { ...handle EOF or error... }o algo similar, para recordarle al OP que las operaciones de entrada, en particular, son vulnerables a comportamientos inesperados. Otras respuestas también necesitan esto.
Jonathan Leffler
215

No "falla"; solo deja de leer. Ve una ficha léxica como una "cadena".

Uso std::getline:

int main()
{
   std::string name, title;

   std::cout << "Enter your name: ";
   std::getline(std::cin, name);

   std::cout << "Enter your favourite movie: ";
   std::getline(std::cin, title);

   std::cout << name << "'s favourite movie is " << title;
}

Tenga en cuenta que esto no es lo mismo que std::istream::getline, que funciona con charbuffers de estilo C en lugar de std::strings.

Actualizar

Su pregunta editada se parece poco al original.

Intentabas getlineingresar a un intbúfer de caracteres o cadenas. Las operaciones de formateo de secuencias solo funcionan con operator<<y operator>>. Utilice uno de ellos (y ajuste en consecuencia para la entrada de varias palabras), o utilice getliney convierta léxicamente a intposteriori.

Carreras de ligereza en órbita
fuente
2
Me gusta esta respuesta mucho mejor que la aceptada, porque no necesito especificar una longitud de caracteres.
TheWanderer
1
@TheWanderer De hecho, ese es un beneficio significativo.
Carreras ligeras en órbita el
Recuerde incluir sstream: #include <sstream>
GilbertS
@LightnessRacesinOrbit, ¿puedes ayudarme? Esto me da una nueva línea adicional sin ningún motivo al imprimir mi salida.
Anshuman Kumar
@AnshumanKumar Creo que getlinepuede incluir la nueva línea de terminación en la cadena que devuelve. Si es así, depende de usted eliminarlo.
Mark Ransom
31

La Biblioteca estándar proporciona una función de entrada llamada ws, que consume espacios en blanco de una secuencia de entrada. Puedes usarlo así:

std::string s;
std::getline(std::cin >> std::ws, s);
dev gr
fuente
44
Creo que esta es la mejor respuesta hasta ahora. Puedo combinar esto con el std :: cin >> arriba.
Andra
1
La mejor respuesta hasta ahora. Al usarlo, std::getline(std::cin, s)me pondría muy desordenado y diría que la entrada interrumpida al esperar entradas en un while/ forloop. ¡Esta opción resolvió mi problema!
omerowitz
Incluir sstream: #include <sstream>
GilbertS
24

Utilizar :

getline(cin, input);

la función se puede encontrar en

#include <string>
Gautham Vinod
fuente
2
+1 Esta es la única respuesta que realmente funcionó para mí. El resto de las respuestas dicen usar cin.getline () pero eso me dio un error diciendo que la función no existe.
blembo
77
@blembo: ¿En serio? Porque mi respuesta, publicada más de tres años antes de esta, dice exactamente lo mismo (a diferencia de lo que usted dice que dice).
ligereza corre en órbita el
@blembo: Y si cin.getlineno existe en su sistema, ha hecho algo muy mal. Lo más probable es que pasaras los argumentos equivocados. Es mejor no culpar a otros por tus errores ...
ligereza corre en órbita el
13

Desea utilizar la función .getline en cin.

#include <iostream>
using namespace std;

int main () {
  char name[256], title[256];

  cout << "Enter your name: ";
  cin.getline (name,256);

  cout << "Enter your favourite movie: ";
  cin.getline (title,256);

  cout << name << "'s favourite movie is " << title;

  return 0;
}

Tomé el ejemplo de aquí . Compruébalo para más información y ejemplos.

Cody
fuente
12
De hecho, rara vez quieres usar member- getline. Está pasado de moda. Use free getlineen su lugar, que se puede usar con std::string. [Por cierto, cplusplus.com no es un recurso recomendado]
Carreras de ligereza en órbita
1
@Tomalak ¿Por qué no se recomienda cplusplus.com? Lo uso todo el tiempo: P
limón
66
@KevinDuke: Los tutoriales pueden ser engañosos e inexactos, y la referencia contiene una multitud de errores. Estos son buenos recursos.
Carreras de ligereza en órbita
1
@NickSweeting: Sí; use esto en su lugar.
Carreras de ligereza en órbita
1
Para enlaces de documentación, cppreference.com es un reemplazo efectivo de cplusplus.com (ambas son paráfrasis no oficiales)
Ben Voigt
4

EL CAMINO C

Puede usar la getsfunción que se encuentra en cstdio (stdio.h en c):

#include<cstdio>
int main(){

char name[256];
gets(name); // for input
puts(name);// for printing 
}

EL CAMINO C ++

gets se elimina en c ++ 11.

[Recomendado]: puede usar getline (cin, nombre) que está en string.h o cin.getline (nombre, 256) que está en iostreamsí mismo.

#include<iostream>
#include<string>
using namespace std;
int main(){

char name1[256];
string name2;
cin.getline(name1,256); // for input
getline(cin,name2); // for input
cout<<name1<<"\n"<<name2;// for printing
}
abe312
fuente
10
Muy mal consejo, getses imposible de usar de forma segura. Incluso se ha eliminado por completo en C11.
Mat
1

Prefiero utilizar el siguiente método para obtener la entrada:

#include <iostream>
#include <string>

using namespace std;

int main(void) {
    string name;

    cout << "Hello, Input your name please: ";
    getline(cin, name);

    return 0;
}

En realidad, es muy fácil de usar en lugar de definir la longitud total de la matriz para una cadena que contiene un carácter de espacio.

Rohan Bari
fuente