std::cin input with spaces?

651,448

Solution 1

You have to use cin.getline():

char input[100];
cin.getline(input,sizeof(input));

Solution 2

It doesn't "fail"; it just stops reading. It sees a lexical token as a "string".

Use std::getline:

#include <string>
#include <iostream>

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

Note that this is not the same as std::istream::getline, which works with C-style char buffers rather than std::strings.

Update

Your edited question bears little resemblance to the original.

You were trying to getline into an int, not a string or character buffer. The formatting operations of streams only work with operator<< and operator>>. Either use one of them (and tweak accordingly for multi-word input), or use getline and lexically convert to int after-the-fact.

Solution 3

The Standard Library provides an input function called ws, which consumes whitespace from an input stream. You can use it like this:

std::string s;
std::getline(std::cin >> std::ws, s);

Solution 4

Use :

getline(cin, input);

the function can be found in

#include <string>

Solution 5

You want to use the .getline function in 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;
}

Took the example from here. Check it out for more info and examples.

Share:
651,448

Related videos on Youtube

dukevin
Author by

dukevin

.-"-.__ | .' / ,-| ```'-, || . ` / /@)|_ `-, | / ( ~ \_```""--.,_', : _.' \ /```''''""`^ / | / `| : / \/ | | . / __/ | |. | | __/ / | | | "-._ | _/ _/=_// || : '. `~~`~^| /=/-_/_/`~~`~~~`~~`~^~`. `&gt; ' . \ ~/_/_ /" ` . ` ' . | .' ,'~^~`^| |~^`^~~`~~~^~~~^~`; ' .-' | | | \ ` : ` | :| | : | |: | || ' | |/ | | : |_/ | . '

Updated on November 16, 2021

Comments

  • dukevin
    dukevin over 2 years
    #include <string>
    
    std::string input;
    std::cin >> input;
    

    The user wants to enter "Hello World". But cin fails at the space between the two words. How can I make cin take in the whole of Hello World?

    I'm actually doing this with structs and cin.getline doesn't seem to work. Here's my 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);
    

    This yields an error. Any ideas?

    • Pete
      Pete about 13 years
      You shouldn't edit your questions to ask new questions like that. The reason is that people have already given answers to your original question and now those answers seem out of context. If your original question has already been answered just start a new question to avoid confusion.
    • chandsie
      chandsie about 13 years
      It's apparent after a little examination, but could you please add a declaration for the variable library so that it's clear that it is of the type cd
    • dukevin
      dukevin about 13 years
      there's good stuff here, no need to delete
    • Ben Voigt
      Ben Voigt over 10 years
      In your update, you're trying to getline into an int. Of course that fails.
    • Some programmer dude
      Some programmer dude about 6 years
      You should probably know this by now (considering the age of this question) but you're really using structures and array wrong. You should have a structure with a single CDTitle, a single Artist and a single number_of_songs. Then have an array (or better yet a std::vector) of the structure.
  • Pete
    Pete about 13 years
    @Kevin Meh, it happens. C++ isn't exactly as intuitive as we would like it to be.
  • Lightness Races in Orbit
    Lightness Races in Orbit about 13 years
    Ew; why use char-buffers? It's 2011.
  • Lightness Races in Orbit
    Lightness Races in Orbit about 13 years
    In fact, you rarely want to use member-getline. It's outmoded. Use free getline instead, which can be used with std::string. [BTW, cplusplus.com is not a recommended resource]
  • jamesbtate
    jamesbtate about 13 years
    Then what should I use? On the rare occasion I am doing c++ and need a reference, cplusplus.com is always the first google result for me.
  • dukevin
    dukevin about 13 years
    @Tomalak Why is cplusplus.com not recommended? I use it all the time :P
  • Lightness Races in Orbit
    Lightness Races in Orbit about 13 years
    @KevinDuke: The tutorials can be misleading and inaccurate, and the reference contains a multitude of errors. These are good resources.
  • Jonathan Leffler
    Jonathan Leffler almost 11 years
    And why not use cin.getline(input, sizeof(input));? Also, shouldn't you check the return status?
  • Pete
    Pete almost 11 years
    @JonathanLeffler At the time this was written, this was the answer I had for the question that was originally asked (look at the first comment for the actual question and you will see that the context had changed due to an edit by the OP). Either way, if you feel the answer is that terrible, downvote it. I acknowledge that this may not be the "best" solution but it's a solution no less. Instead of asking why I didn't use something, you could tell us all why we should do it your way.
  • Jonathan Leffler
    Jonathan Leffler almost 11 years
    Your answer is not terrible and doesn't need downvoting. I do think two small changes would improve it. Change 1 would use sizeof(input) in place of 100 in the call to cin.getline(); that would mean you can change the size of the input buffer and only need to change one line instead of two lines. Change 2 would be to test the return from cin.getline() by using, for example, if (!cin.getline(input, sizeof(input))) { ...handle EOF or error... } or something similar, to remind the OP that input operations, in particular, are vulnerable to unexpected behaviour. Other answers need this too.
  • Nick Sweeting
    Nick Sweeting about 10 years
    Dead link? @LightnessRacesinOrbit
  • Lightness Races in Orbit
    Lightness Races in Orbit about 10 years
    @NickSweeting: Yeah; use this instead.
  • Ben Voigt
    Ben Voigt almost 10 years
    For documentation links, cppreference.com is an effective replacement for cplusplus.com (both are non-official paraphrases)
  • Mat
    Mat almost 9 years
    Very bad advice, gets is impossible to use safely. It's even been removed completely in C11.
  • blembo
    blembo over 8 years
    +1 This is the only answer that actually worked for me. The rest of the answers say to use cin.getline() but that just gave me an error saying the function doesn't exist.
  • Lightness Races in Orbit
    Lightness Races in Orbit over 6 years
    @blembo: Really? Because my answer, posted more than three years before this one, says the exact same thing (as opposed to what you claim it says).
  • Lightness Races in Orbit
    Lightness Races in Orbit over 6 years
    @blembo: And if cin.getline doesn't exist on your system, you have done something very wrong. Most likely you were passing the wrong arguments. Best not to blame others for your mistakes...
  • TheWanderer
    TheWanderer over 5 years
    I like this answer much better than the accepted one, because I don't need to specify a character length.
  • Lightness Races in Orbit
    Lightness Races in Orbit over 5 years
    @TheWanderer Indeed, that's a significant benefit.
  • Andra
    Andra over 5 years
    I think this is the best answer so far. I can combine this with the std::cin>> on above.
  • Zlatan Omerović
    Zlatan Omerović over 4 years
    Best answer so far. When using std::getline(std::cin, s) I would get a very messy and I would say, interrupted input when waiting for inputs in a while/for loop. This option resolved my issue!
  • GilbertS
    GilbertS about 4 years
    Include sstream: #include <sstream>
  • Anshuman Kumar
    Anshuman Kumar almost 4 years
    @LightnessRacesinOrbit, can you please help? This gives me an extra newline for no reason while printing my output.
  • Mark Ransom
    Mark Ransom almost 4 years
    @AnshumanKumar I think getline may include the terminating newline in the string it returns. If so, it's up to you to delete it.
  • Ardent Coder
    Ardent Coder about 3 years
    @LightnessRacesinOrbit I understand how this answer can be viewed as a subset of your answer (content-wise). The problem mentioned in that comment might have been a consequence of the difference in presentation and the order of answers in this thread (wrt. the tick & votes). If a speed reader begins unsatisfied with the C-style getline, followed by a much longer answer of yours (though useful for focused readers), followed by another way of using getline, the reader may finally conclude that this answer is the better of them, which basically resembles yours, but in a concise manner.
  • Pedro Silveira
    Pedro Silveira almost 2 years
    I'm trying to achieve exactly what's been suggested and it doesn't work for me. It prints "Enter your name: Enter your favorite movie" ...
  • Syed Nasir Abbas
    Syed Nasir Abbas almost 2 years
    Use ws (whitespace) in getline() like getline(cin>>ws, name); If numeric input is before the string then due to whitespace the first string input will be ignored. Therefore use ws like getline(cin>>ws, name); #include <iostream> using namespace std; main(){ int id=0; string name, address; cout <<"Id? "; cin>>id; cout <<"Name? "; getline(cin>>ws, name); cout <<"Address? "; getline(cin>>ws, address); cout <<"\nName: " <<name <<"\nAddress: " <<address; }