entrée std :: cin avec des espaces?

144
#include <string>

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

L'utilisateur veut entrer "Hello World". Mais cinéchoue à l'espace entre les deux mots. Comment puis-je faire cinprendre à l'ensemble de Hello World?

Je fais en fait cela avec des structures et cin.getlinene semble pas fonctionner. Voici mon code:

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

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

Cela génère une erreur. Des idées?

citron
la source
27
Vous ne devriez pas modifier vos questions pour poser de nouvelles questions comme celle-là. La raison en est que les gens ont déjà donné des réponses à votre question initiale et maintenant ces réponses semblent hors contexte. Si votre question initiale a déjà reçu une réponse, commencez simplement une nouvelle question pour éviter toute confusion.
Pete
C'est apparent après un petit examen, mais pourriez-vous s'il vous plaît ajouter une déclaration pour la variable libraryafin qu'il soit clair qu'elle est du typecd
chandsie
désolé les gars, cela a été fait à la hâte, je vais republier ceci.
citron
1
Si vous prévoyez de le republier à titre de remplacement, veuillez signaler la question à supprimer par un mod.
Courses de légèreté en orbite le
2
Dans votre mise à jour, vous essayez d' getlineentrer dans un fichier int. Bien sûr, cela échoue.
Ben Voigt

Réponses:

102

Vous devez utiliser cin.getline():

char input[100];
cin.getline(input,sizeof(input));
Pete
la source
7
@Kevin Meh, ça arrive. C ++ n'est pas exactement aussi intuitif que nous le souhaiterions.
Pete
62
Ew; pourquoi utiliser char-buffers? Nous
sommes
3
Et pourquoi ne pas l'utiliser cin.getline(input, sizeof(input));? De plus, ne devriez-vous pas vérifier l'état du retour?
Jonathan Leffler
2
@JonathanLeffler Au moment où cela a été écrit, c'était la réponse que j'avais pour la question qui avait été initialement posée (regardez le premier commentaire pour la question réelle et vous verrez que le contexte avait changé en raison d'une modification par l'OP). Dans tous les cas, si vous pensez que la réponse est si terrible, votez contre. Je reconnais que ce n'est peut-être pas la «meilleure» solution, mais ce n'en est pas moins une solution. Au lieu de demander pourquoi je n'ai pas utilisé quelque chose, vous pourriez nous dire à tous pourquoi nous devrions le faire à votre façon.
Pete
7
Votre réponse n'est pas terrible et ne nécessite pas de vote négatif. Je pense que deux petits changements l'amélioreraient. Le changement 1 utiliserait sizeof(input)à la place de 100 dans l'appel à cin.getline(); cela signifierait que vous pouvez changer la taille du tampon d'entrée et n'avez besoin de changer qu'une ligne au lieu de deux lignes. La modification 2 serait de tester le retour de cin.getline()en utilisant, par exemple, if (!cin.getline(input, sizeof(input))) { ...handle EOF or error... }ou quelque chose de similaire, pour rappeler à l'OP que les opérations d'entrée, en particulier, sont vulnérables à un comportement inattendu. D'autres réponses en ont également besoin.
Jonathan Leffler
215

Cela n'échoue pas; il arrête juste de lire. Il voit un jeton lexical comme une "chaîne".

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

Notez que ce n'est pas la même chose que std::istream::getline, qui fonctionne avec des chartampons de style C plutôt que std::strings.

Mettre à jour

Votre question modifiée ne ressemble guère à l'original.

Vous avez essayé d' getlineentrer dans un inttampon, pas une chaîne ou un caractère. Les opérations de formatage des flux fonctionnent uniquement avec operator<<et operator>>. Utilisez l'un d'entre eux (et ajustez-le en conséquence pour une entrée de plusieurs mots), ou utilisez getlineet convertissez lexicalement en intaprès-coup.

Courses de légèreté en orbite
la source
2
J'aime beaucoup mieux cette réponse que celle acceptée, car je n'ai pas besoin de spécifier une longueur de caractère.
TheWanderer
1
@TheWanderer En effet, c'est un avantage considérable.
Courses de légèreté en orbite le
N'oubliez pas d'inclure sstream: #include <sstream>
GilbertS
@LightnessRacesinOrbit, pouvez-vous nous aider? Cela me donne une nouvelle ligne supplémentaire sans raison lors de l'impression de ma sortie.
Anshuman Kumar le
@AnshumanKumar Je pense que getlinepeut inclure la nouvelle ligne de fin dans la chaîne qu'il renvoie. Si tel est le cas, c'est à vous de le supprimer.
Mark Ransom le
31

La bibliothèque standard fournit une fonction d'entrée appelée ws, qui consomme des espaces d'un flux d'entrée. Vous pouvez l'utiliser comme ceci:

std::string s;
std::getline(std::cin >> std::ws, s);
dev gr
la source
4
Je pense que c'est la meilleure réponse à ce jour. Je peux combiner cela avec le std :: cin >> ci-dessus.
Andra
1
Meilleure réponse à ce jour. Lors de l'utilisation std::getline(std::cin, s), j'obtiendrais une entrée très désordonnée et je dirais, interrompue lors de l'attente d'entrées dans une boucle while/ for. Cette option a résolu mon problème!
omerowitz
Inclure sstream: #include <sstream>
GilbertS
24

Utilisation :

getline(cin, input);

la fonction se trouve dans

#include <string>
Gautham Vinod
la source
2
+1 C'est la seule réponse qui a réellement fonctionné pour moi. Le reste des réponses dit d'utiliser cin.getline () mais cela m'a juste donné une erreur disant que la fonction n'existe pas.
blembo
7
@blembo: Vraiment? Parce que ma réponse, postée plus de trois ans avant celle-ci, dit exactement la même chose (par opposition à ce que vous prétendez qu'elle dit).
Courses de légèreté en orbite le
@blembo: Et s'il cin.getlinen'existe pas sur votre système, vous avez fait quelque chose de très mal. Il est fort probable que vous passiez les mauvais arguments. Mieux vaut ne pas blâmer les autres pour vos erreurs ...
Courses de légèreté en orbite
13

Vous souhaitez utiliser la fonction .getline dans 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;
}

J'ai pris l'exemple d' ici . Consultez-le pour plus d'informations et d'exemples.

Cody
la source
12
En fait, vous souhaitez rarement utiliser member- getline. C'est démodé. Utilisez getlineplutôt gratuit , qui peut être utilisé avec std::string. [BTW, cplusplus.com n'est pas une ressource recommandée]
Courses de légèreté en orbite
1
@Tomalak Pourquoi cplusplus.com n'est-il pas recommandé? Je l'utilise tout le temps: P
citron
6
@KevinDuke: Les tutoriels peuvent être trompeurs et inexacts, et la référence contient une multitude d'erreurs. Ce sont de bonnes ressources.
Courses de légèreté en orbite le
1
@NickSweeting: Ouais; utilisez plutôt ceci .
Courses de légèreté en orbite le
1
Pour les liens de documentation, cppreference.com est un remplacement efficace pour cplusplus.com (les deux sont des paraphrases non officielles)
Ben Voigt
4

LA VOIE C

Vous pouvez utiliser la getsfonction trouvée dans cstdio (stdio.h dans c):

#include<cstdio>
int main(){

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

LA VOIE C ++

gets est supprimé dans c ++ 11.

[Recommandé]: Vous pouvez utiliser getline (cin, nom) qui est dans string.h ou cin.getline (nom, 256) qui est en iostreamlui-même.

#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
la source
10
Très mauvais conseil, getsimpossible à utiliser en toute sécurité. Il a même été complètement supprimé dans C11.
Mat
1

J'utilise plutôt la méthode suivante pour obtenir l'entrée:

#include <iostream>
#include <string>

using namespace std;

int main(void) {
    string name;

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

    return 0;
}

C'est en fait très facile à utiliser plutôt que de définir la longueur totale du tableau pour une chaîne contenant un caractère espace.

Rohan Bari
la source