Why does std::getline() skip input after a formatted extraction?cin and getline skipping inputProgram is skipping over Getline() without taking user inputWhy is std::getline() skipped?How do I stop program from skipping over getline?error in getline input in c++String input in standard C++Why won't getline function work multiple times in a for loop with an array of structures?C++ string input inside loopUsing getline(cin, string)inserting a student's name and its ID and show themWhy is “using namespace std;” considered bad practice?Is there any way to change input type=“date” format?Why does changing 0.1f to 0 slow down performance by 10x?errors in C++ code using std, vector and bitvec and how to take input from userUsing getline() with file input in C++reading and parsing a file, assigning each piece of the parsed string to its own variableMake std::getline() on std::stringstream block on eof (or find alternative stream class)C++ Using std::getline in place of cin >>std::getline skipping input from std::cin after last occurrence of delimiter, but not with input from std::istringstreamHow to fix the error of not taking value at 0 position in loop

US citizen traveling with Peruvian passport

Tesco's Burger Relish Best Before End date number

Is "wissen" the only verb in German to have an irregular present tense?

Clarinets in the Rite of Spring

Can Jimmy hang on his rope?

Wires do not connect in Circuitikz

When do flights get cancelled due to fog?

How many Jimmys can fit?

Who goes first? Person disembarking bus or the bicycle?

How should I ask for a "pint" in countries that use metric?

Tikz, arrow formatting

Chilling water in copper vessel

run bash scripts in folder all at the same time

What do you call a situation where you have choices but no good choice?

Writing an ace/aro character?

Moving millions of files to a different directory with specfic name patterns

How to slice a string input at a certain unknown index

With a data transfer of 50 GB estimated 5 hours, are USB-C claimed speeds inaccurate or to blame?

This LM317 diagram doesn't make any sense to me

Why am I getting unevenly-spread results when using $RANDOM?

What does the multimeter dial do internally?

How do I explain that I don't want to maintain old projects?

stuck in/at beta

How to evaluate the performance of open source solver?



Why does std::getline() skip input after a formatted extraction?


cin and getline skipping inputProgram is skipping over Getline() without taking user inputWhy is std::getline() skipped?How do I stop program from skipping over getline?error in getline input in c++String input in standard C++Why won't getline function work multiple times in a for loop with an array of structures?C++ string input inside loopUsing getline(cin, string)inserting a student's name and its ID and show themWhy is “using namespace std;” considered bad practice?Is there any way to change input type=“date” format?Why does changing 0.1f to 0 slow down performance by 10x?errors in C++ code using std, vector and bitvec and how to take input from userUsing getline() with file input in C++reading and parsing a file, assigning each piece of the parsed string to its own variableMake std::getline() on std::stringstream block on eof (or find alternative stream class)C++ Using std::getline in place of cin >>std::getline skipping input from std::cin after last occurrence of delimiter, but not with input from std::istringstreamHow to fix the error of not taking value at 0 position in loop






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;








87















I have the following piece of code that prompts the user for their name and state:



#include <iostream>
#include <string>

int main()

std::string name;
std::string state;

if (std::cin >> name && std::getline(std::cin, state))

std::cout << "Your name is " << name << " and you live in " << state;




What I find is that the name has been successfully extracted, but not the state. Here is the input and resulting output:




Input:

"John"
"New Hampshire"

Output:

"Your name is John and you live in "



Why has the name of the state been omitted from the output? I've given the proper input, but the code somehow ignores it. Why does this happen?










share|improve this question
























  • I believe std::cin >> name && std::cin >> std::skipws && std::getline(std::cin, state) should also work as expected. (In addition to the answers below).

    – jww
    Nov 11 '18 at 17:30


















87















I have the following piece of code that prompts the user for their name and state:



#include <iostream>
#include <string>

int main()

std::string name;
std::string state;

if (std::cin >> name && std::getline(std::cin, state))

std::cout << "Your name is " << name << " and you live in " << state;




What I find is that the name has been successfully extracted, but not the state. Here is the input and resulting output:




Input:

"John"
"New Hampshire"

Output:

"Your name is John and you live in "



Why has the name of the state been omitted from the output? I've given the proper input, but the code somehow ignores it. Why does this happen?










share|improve this question
























  • I believe std::cin >> name && std::cin >> std::skipws && std::getline(std::cin, state) should also work as expected. (In addition to the answers below).

    – jww
    Nov 11 '18 at 17:30














87












87








87


47






I have the following piece of code that prompts the user for their name and state:



#include <iostream>
#include <string>

int main()

std::string name;
std::string state;

if (std::cin >> name && std::getline(std::cin, state))

std::cout << "Your name is " << name << " and you live in " << state;




What I find is that the name has been successfully extracted, but not the state. Here is the input and resulting output:




Input:

"John"
"New Hampshire"

Output:

"Your name is John and you live in "



Why has the name of the state been omitted from the output? I've given the proper input, but the code somehow ignores it. Why does this happen?










share|improve this question
















I have the following piece of code that prompts the user for their name and state:



#include <iostream>
#include <string>

int main()

std::string name;
std::string state;

if (std::cin >> name && std::getline(std::cin, state))

std::cout << "Your name is " << name << " and you live in " << state;




What I find is that the name has been successfully extracted, but not the state. Here is the input and resulting output:




Input:

"John"
"New Hampshire"

Output:

"Your name is John and you live in "



Why has the name of the state been omitted from the output? I've given the proper input, but the code somehow ignores it. Why does this happen?







c++ input iostream istream c++-faq






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 23 '16 at 16:02









πάντα ῥεῖ

1




1










asked Feb 5 '14 at 2:01









0x499602D20x499602D2

70.1k29 gold badges124 silver badges211 bronze badges




70.1k29 gold badges124 silver badges211 bronze badges












  • I believe std::cin >> name && std::cin >> std::skipws && std::getline(std::cin, state) should also work as expected. (In addition to the answers below).

    – jww
    Nov 11 '18 at 17:30


















  • I believe std::cin >> name && std::cin >> std::skipws && std::getline(std::cin, state) should also work as expected. (In addition to the answers below).

    – jww
    Nov 11 '18 at 17:30

















I believe std::cin >> name && std::cin >> std::skipws && std::getline(std::cin, state) should also work as expected. (In addition to the answers below).

– jww
Nov 11 '18 at 17:30






I believe std::cin >> name && std::cin >> std::skipws && std::getline(std::cin, state) should also work as expected. (In addition to the answers below).

– jww
Nov 11 '18 at 17:30













3 Answers
3






active

oldest

votes


















103














Why does this happen?



This has little to do with the input you provided yourself but rather with the default behavior std::getline() exhibits. When you provided your input for the name (std::cin >> name), you not only submitted the following characters, but also an implicit newline was appended to the stream:




"Johnn"



A newline is always appended to your input when you select Enter or Return when submitting from a terminal. It is also used in files for moving toward the next line. The newline is left in the buffer after the extraction into name until the next I/O operation where it is either discarded or consumed. When the flow of control reaches std::getline(), the newline will be discarded, but the input will cease immediately. The reason this happens is because the default functionality of this function dictates that it should (it attempts to read a line and stops when it finds a newline).



Because this leading newline inhibits the expected functionality of your program, it follows that it must be skipped our ignored somehow. One option is to call std::cin.ignore() after the the first extraction. It will discard the next available character so that the newline is no longer intrusive.




In-Depth Explanation:



This is the overload of std::getline() that you called:




template<class charT>
std::basic_istream<charT>& getline( std::basic_istream<charT>& input,
std::basic_string<charT>& str )



Another overload of this function takes a delimiter of type charT. A delimiter character is a character that represents the boundary between sequences of input. This particular overload sets the delimiter to the newline character input.widen('n') by default since one was not supplied.



Now, these are a few of the conditions whereby std::getline() terminates input:



  • If the stream has extracted the maximum amount of characters a std::basic_string<charT> can hold

  • If the end-of-file (EOF) character has been found

  • If the delimiter has been found

The third condition is the one we're dealing with. Your input into state is represented thusly:




"JohnnNew Hampshire"
^
|
next_pointer



where next_pointer is the next character to be parsed. Since the character stored at the next position in the input sequence is the delimiter, std::getline() will quietly discard that character, increment next_pointer to the next available character, and stop input. This means that the rest of the characters that you have provided still remain in the buffer for the next I/O operation. You'll notice that if you perform another read from the line into state, your extraction will yield the correct result as the last call to std::getline() discarded the delimiter.




You may have noticed that you don't typically run into this problem when extracting with the formatted input operator (operator>>()). This is because input streams use whitespace as delimiters for input and have the std::skipws1 manipulator set on by default. Streams will discard the leading whitespace from the stream when beginning to perform formatted input.2



Unlike the formatted input operators, std::getline() is an unformatted input function. And all unformatted input functions have the following code somewhat in common:



typename std::basic_istream<charT>::sentry ok(istream_object, true);


The above is a sentry object which is instantiated in all formatted/unformatted I/O functions in a standard C++ implementation. Sentry objects are used for preparing the stream for I/O and determining whether or not it is in a fail state. You'll only find that in the unformatted input functions, the second argument to the sentry constructor is true. That argument means that leading whitespace will not be discarded from the beginning of the input sequence. Here is the relevant quote from the Standard [§27.7.2.1.3/2]:




 explicit sentry(basic_istream<charT, traits>& is, bool noskipws = false);


[...] If noskipws is zero and is.flags() & ios_base::skipws is nonzero, the function extracts and discards each character as long as the next available input character c is a whitespace character. [...]




Since the above condition is false, the sentry object will not discard the whitespace. The reason noskipws is set to true by this function is because the point of std::getline() is to read raw, unformatted characters into a std::basic_string<charT> object.




The Solution:



There's no way to stop this behavior of std::getline(). What you'll have to do is discard the new line yourself before std::getline() runs (but do it after the formatted extraction). This can be done by using ignore() to discard the rest of the input until we reach a fresh new line:



if (std::cin >> name &&
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n') &&
std::getline(std::cin, state))
...


You'll need to include <limits> to use std::numeric_limits. std::basic_istream<...>::ignore() is a function that discards a specified amount of characters until it either finds a delimiter or reaches the end of the stream (ignore() also discards the delimiter if it finds it). The max() function returns the largest amount of characters that a stream can accept.



Another way to discard the whitespace is to use the std::ws function which is a manipulator designed to extract and discard leading whitespace from the beginning of an input stream:



if (std::cin >> name && std::getline(std::cin >> std::ws, state))
...


What's the difference?



The difference is that ignore(std::streamsize count = 1, int_type delim = Traits::eof())3 indiscriminately discards characters until it either discards count characters, finds the delimiter (specified by the second argument delim) or hits the end of the stream. std::ws is only used for discarding whitespace characters from the beginning of the stream.



If you are mixing formatted input with unformatted input and you need to discard residual whitespace, use std::ws. Otherwise, if you need to clear out invalid input regardless of what it is, use ignore(). In our example, we only need to clear whitespace since the stream consumed your input of "John" for the name variable. All that was left was the newline character.




1: std::skipws is manipulator that tells the input stream to discard leading whitespace when performing formatted input. This can be turned off with the std::noskipws manipulator.



2: Input streams deem certain characters as whitespace by default, such the space character, newline character, form feed, carriage return, etc.



3: This is the signature of std::basic_istream<...>::ignore(). You can call it with zero arguments to discard a single character from the stream, one argument to discard a certain amount of characters, or two arguments to discard count characters or until it reaches delim, whichever one comes first. You normally use std::numeric_limits<std::streamsize>::max() as the value of count if you don't know how many characters there are before the delimiter, but you want to discard them anyway.






share|improve this answer

























  • Why not simply if (getline(std::cin, name) && getline(std::cin, state))?

    – Fred Larson
    Aug 19 '16 at 19:41











  • @FredLarson Good point. Though it wouldn't work if the first extraction is of an integer or anything that isn't a string.

    – 0x499602D2
    Aug 19 '16 at 20:30












  • Of course, that isn't the case here and there's no point in doing the same thing two different ways. For an integer you could get the line into a string and then use std::stoi(), but then it's not so clear there's an advantage. But I tend to prefer to just use std::getline() for line-oriented input and then deal with parsing the line in whatever way makes sense. I think it's less error prone.

    – Fred Larson
    Aug 19 '16 at 20:35











  • @FredLarson Agreed. Maybe I'll add that in if I have the time.

    – 0x499602D2
    Aug 19 '16 at 20:39


















10














Everything will be OK if you change your initial code in the following way:



if ((cin >> name).get() && std::getline(cin, state))





share|improve this answer




















  • 2





    Thank you. This will also work because get() consumes the next character. There's also (std::cin >> name).ignore() which I suggested earlier in my answer.

    – 0x499602D2
    Mar 26 '14 at 12:14











  • "..work because get()..." Yes, exactly. Sorry for giving the answer without details.

    – Boris
    Mar 26 '14 at 13:14







  • 4





    Why not simply if (getline(std::cin, name) && getline(std::cin, state))?

    – Fred Larson
    Aug 19 '16 at 19:41


















0














This happens because an implicit line feed also known as newline character n is appended to all user input from a terminal as it's telling the stream to start a new line. You can safely account for this by using std::getline when checking for multiple lines of user input. The default behavior of std::getline will read everything up to and including the newline character n from the input stream object which is std::cin in this case.



#include <iostream>
#include <string>

int main()

std::string name;
std::string state;

if (std::getline(std::cin, name) && std::getline(std::cin, state))

std::cout << "Your name is " << name << " and you live in " << state;

return 0;




Input:

"John"
"New Hampshire"

Output:

"Your name is John and you live in New Hampshire"






share|improve this answer

























    protected by StoryTeller Dec 6 '17 at 8:53



    Thank you for your interest in this question.
    Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



    Would you like to answer one of these unanswered questions instead?














    3 Answers
    3






    active

    oldest

    votes








    3 Answers
    3






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    103














    Why does this happen?



    This has little to do with the input you provided yourself but rather with the default behavior std::getline() exhibits. When you provided your input for the name (std::cin >> name), you not only submitted the following characters, but also an implicit newline was appended to the stream:




    "Johnn"



    A newline is always appended to your input when you select Enter or Return when submitting from a terminal. It is also used in files for moving toward the next line. The newline is left in the buffer after the extraction into name until the next I/O operation where it is either discarded or consumed. When the flow of control reaches std::getline(), the newline will be discarded, but the input will cease immediately. The reason this happens is because the default functionality of this function dictates that it should (it attempts to read a line and stops when it finds a newline).



    Because this leading newline inhibits the expected functionality of your program, it follows that it must be skipped our ignored somehow. One option is to call std::cin.ignore() after the the first extraction. It will discard the next available character so that the newline is no longer intrusive.




    In-Depth Explanation:



    This is the overload of std::getline() that you called:




    template<class charT>
    std::basic_istream<charT>& getline( std::basic_istream<charT>& input,
    std::basic_string<charT>& str )



    Another overload of this function takes a delimiter of type charT. A delimiter character is a character that represents the boundary between sequences of input. This particular overload sets the delimiter to the newline character input.widen('n') by default since one was not supplied.



    Now, these are a few of the conditions whereby std::getline() terminates input:



    • If the stream has extracted the maximum amount of characters a std::basic_string<charT> can hold

    • If the end-of-file (EOF) character has been found

    • If the delimiter has been found

    The third condition is the one we're dealing with. Your input into state is represented thusly:




    "JohnnNew Hampshire"
    ^
    |
    next_pointer



    where next_pointer is the next character to be parsed. Since the character stored at the next position in the input sequence is the delimiter, std::getline() will quietly discard that character, increment next_pointer to the next available character, and stop input. This means that the rest of the characters that you have provided still remain in the buffer for the next I/O operation. You'll notice that if you perform another read from the line into state, your extraction will yield the correct result as the last call to std::getline() discarded the delimiter.




    You may have noticed that you don't typically run into this problem when extracting with the formatted input operator (operator>>()). This is because input streams use whitespace as delimiters for input and have the std::skipws1 manipulator set on by default. Streams will discard the leading whitespace from the stream when beginning to perform formatted input.2



    Unlike the formatted input operators, std::getline() is an unformatted input function. And all unformatted input functions have the following code somewhat in common:



    typename std::basic_istream<charT>::sentry ok(istream_object, true);


    The above is a sentry object which is instantiated in all formatted/unformatted I/O functions in a standard C++ implementation. Sentry objects are used for preparing the stream for I/O and determining whether or not it is in a fail state. You'll only find that in the unformatted input functions, the second argument to the sentry constructor is true. That argument means that leading whitespace will not be discarded from the beginning of the input sequence. Here is the relevant quote from the Standard [§27.7.2.1.3/2]:




     explicit sentry(basic_istream<charT, traits>& is, bool noskipws = false);


    [...] If noskipws is zero and is.flags() & ios_base::skipws is nonzero, the function extracts and discards each character as long as the next available input character c is a whitespace character. [...]




    Since the above condition is false, the sentry object will not discard the whitespace. The reason noskipws is set to true by this function is because the point of std::getline() is to read raw, unformatted characters into a std::basic_string<charT> object.




    The Solution:



    There's no way to stop this behavior of std::getline(). What you'll have to do is discard the new line yourself before std::getline() runs (but do it after the formatted extraction). This can be done by using ignore() to discard the rest of the input until we reach a fresh new line:



    if (std::cin >> name &&
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n') &&
    std::getline(std::cin, state))
    ...


    You'll need to include <limits> to use std::numeric_limits. std::basic_istream<...>::ignore() is a function that discards a specified amount of characters until it either finds a delimiter or reaches the end of the stream (ignore() also discards the delimiter if it finds it). The max() function returns the largest amount of characters that a stream can accept.



    Another way to discard the whitespace is to use the std::ws function which is a manipulator designed to extract and discard leading whitespace from the beginning of an input stream:



    if (std::cin >> name && std::getline(std::cin >> std::ws, state))
    ...


    What's the difference?



    The difference is that ignore(std::streamsize count = 1, int_type delim = Traits::eof())3 indiscriminately discards characters until it either discards count characters, finds the delimiter (specified by the second argument delim) or hits the end of the stream. std::ws is only used for discarding whitespace characters from the beginning of the stream.



    If you are mixing formatted input with unformatted input and you need to discard residual whitespace, use std::ws. Otherwise, if you need to clear out invalid input regardless of what it is, use ignore(). In our example, we only need to clear whitespace since the stream consumed your input of "John" for the name variable. All that was left was the newline character.




    1: std::skipws is manipulator that tells the input stream to discard leading whitespace when performing formatted input. This can be turned off with the std::noskipws manipulator.



    2: Input streams deem certain characters as whitespace by default, such the space character, newline character, form feed, carriage return, etc.



    3: This is the signature of std::basic_istream<...>::ignore(). You can call it with zero arguments to discard a single character from the stream, one argument to discard a certain amount of characters, or two arguments to discard count characters or until it reaches delim, whichever one comes first. You normally use std::numeric_limits<std::streamsize>::max() as the value of count if you don't know how many characters there are before the delimiter, but you want to discard them anyway.






    share|improve this answer

























    • Why not simply if (getline(std::cin, name) && getline(std::cin, state))?

      – Fred Larson
      Aug 19 '16 at 19:41











    • @FredLarson Good point. Though it wouldn't work if the first extraction is of an integer or anything that isn't a string.

      – 0x499602D2
      Aug 19 '16 at 20:30












    • Of course, that isn't the case here and there's no point in doing the same thing two different ways. For an integer you could get the line into a string and then use std::stoi(), but then it's not so clear there's an advantage. But I tend to prefer to just use std::getline() for line-oriented input and then deal with parsing the line in whatever way makes sense. I think it's less error prone.

      – Fred Larson
      Aug 19 '16 at 20:35











    • @FredLarson Agreed. Maybe I'll add that in if I have the time.

      – 0x499602D2
      Aug 19 '16 at 20:39















    103














    Why does this happen?



    This has little to do with the input you provided yourself but rather with the default behavior std::getline() exhibits. When you provided your input for the name (std::cin >> name), you not only submitted the following characters, but also an implicit newline was appended to the stream:




    "Johnn"



    A newline is always appended to your input when you select Enter or Return when submitting from a terminal. It is also used in files for moving toward the next line. The newline is left in the buffer after the extraction into name until the next I/O operation where it is either discarded or consumed. When the flow of control reaches std::getline(), the newline will be discarded, but the input will cease immediately. The reason this happens is because the default functionality of this function dictates that it should (it attempts to read a line and stops when it finds a newline).



    Because this leading newline inhibits the expected functionality of your program, it follows that it must be skipped our ignored somehow. One option is to call std::cin.ignore() after the the first extraction. It will discard the next available character so that the newline is no longer intrusive.




    In-Depth Explanation:



    This is the overload of std::getline() that you called:




    template<class charT>
    std::basic_istream<charT>& getline( std::basic_istream<charT>& input,
    std::basic_string<charT>& str )



    Another overload of this function takes a delimiter of type charT. A delimiter character is a character that represents the boundary between sequences of input. This particular overload sets the delimiter to the newline character input.widen('n') by default since one was not supplied.



    Now, these are a few of the conditions whereby std::getline() terminates input:



    • If the stream has extracted the maximum amount of characters a std::basic_string<charT> can hold

    • If the end-of-file (EOF) character has been found

    • If the delimiter has been found

    The third condition is the one we're dealing with. Your input into state is represented thusly:




    "JohnnNew Hampshire"
    ^
    |
    next_pointer



    where next_pointer is the next character to be parsed. Since the character stored at the next position in the input sequence is the delimiter, std::getline() will quietly discard that character, increment next_pointer to the next available character, and stop input. This means that the rest of the characters that you have provided still remain in the buffer for the next I/O operation. You'll notice that if you perform another read from the line into state, your extraction will yield the correct result as the last call to std::getline() discarded the delimiter.




    You may have noticed that you don't typically run into this problem when extracting with the formatted input operator (operator>>()). This is because input streams use whitespace as delimiters for input and have the std::skipws1 manipulator set on by default. Streams will discard the leading whitespace from the stream when beginning to perform formatted input.2



    Unlike the formatted input operators, std::getline() is an unformatted input function. And all unformatted input functions have the following code somewhat in common:



    typename std::basic_istream<charT>::sentry ok(istream_object, true);


    The above is a sentry object which is instantiated in all formatted/unformatted I/O functions in a standard C++ implementation. Sentry objects are used for preparing the stream for I/O and determining whether or not it is in a fail state. You'll only find that in the unformatted input functions, the second argument to the sentry constructor is true. That argument means that leading whitespace will not be discarded from the beginning of the input sequence. Here is the relevant quote from the Standard [§27.7.2.1.3/2]:




     explicit sentry(basic_istream<charT, traits>& is, bool noskipws = false);


    [...] If noskipws is zero and is.flags() & ios_base::skipws is nonzero, the function extracts and discards each character as long as the next available input character c is a whitespace character. [...]




    Since the above condition is false, the sentry object will not discard the whitespace. The reason noskipws is set to true by this function is because the point of std::getline() is to read raw, unformatted characters into a std::basic_string<charT> object.




    The Solution:



    There's no way to stop this behavior of std::getline(). What you'll have to do is discard the new line yourself before std::getline() runs (but do it after the formatted extraction). This can be done by using ignore() to discard the rest of the input until we reach a fresh new line:



    if (std::cin >> name &&
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n') &&
    std::getline(std::cin, state))
    ...


    You'll need to include <limits> to use std::numeric_limits. std::basic_istream<...>::ignore() is a function that discards a specified amount of characters until it either finds a delimiter or reaches the end of the stream (ignore() also discards the delimiter if it finds it). The max() function returns the largest amount of characters that a stream can accept.



    Another way to discard the whitespace is to use the std::ws function which is a manipulator designed to extract and discard leading whitespace from the beginning of an input stream:



    if (std::cin >> name && std::getline(std::cin >> std::ws, state))
    ...


    What's the difference?



    The difference is that ignore(std::streamsize count = 1, int_type delim = Traits::eof())3 indiscriminately discards characters until it either discards count characters, finds the delimiter (specified by the second argument delim) or hits the end of the stream. std::ws is only used for discarding whitespace characters from the beginning of the stream.



    If you are mixing formatted input with unformatted input and you need to discard residual whitespace, use std::ws. Otherwise, if you need to clear out invalid input regardless of what it is, use ignore(). In our example, we only need to clear whitespace since the stream consumed your input of "John" for the name variable. All that was left was the newline character.




    1: std::skipws is manipulator that tells the input stream to discard leading whitespace when performing formatted input. This can be turned off with the std::noskipws manipulator.



    2: Input streams deem certain characters as whitespace by default, such the space character, newline character, form feed, carriage return, etc.



    3: This is the signature of std::basic_istream<...>::ignore(). You can call it with zero arguments to discard a single character from the stream, one argument to discard a certain amount of characters, or two arguments to discard count characters or until it reaches delim, whichever one comes first. You normally use std::numeric_limits<std::streamsize>::max() as the value of count if you don't know how many characters there are before the delimiter, but you want to discard them anyway.






    share|improve this answer

























    • Why not simply if (getline(std::cin, name) && getline(std::cin, state))?

      – Fred Larson
      Aug 19 '16 at 19:41











    • @FredLarson Good point. Though it wouldn't work if the first extraction is of an integer or anything that isn't a string.

      – 0x499602D2
      Aug 19 '16 at 20:30












    • Of course, that isn't the case here and there's no point in doing the same thing two different ways. For an integer you could get the line into a string and then use std::stoi(), but then it's not so clear there's an advantage. But I tend to prefer to just use std::getline() for line-oriented input and then deal with parsing the line in whatever way makes sense. I think it's less error prone.

      – Fred Larson
      Aug 19 '16 at 20:35











    • @FredLarson Agreed. Maybe I'll add that in if I have the time.

      – 0x499602D2
      Aug 19 '16 at 20:39













    103












    103








    103







    Why does this happen?



    This has little to do with the input you provided yourself but rather with the default behavior std::getline() exhibits. When you provided your input for the name (std::cin >> name), you not only submitted the following characters, but also an implicit newline was appended to the stream:




    "Johnn"



    A newline is always appended to your input when you select Enter or Return when submitting from a terminal. It is also used in files for moving toward the next line. The newline is left in the buffer after the extraction into name until the next I/O operation where it is either discarded or consumed. When the flow of control reaches std::getline(), the newline will be discarded, but the input will cease immediately. The reason this happens is because the default functionality of this function dictates that it should (it attempts to read a line and stops when it finds a newline).



    Because this leading newline inhibits the expected functionality of your program, it follows that it must be skipped our ignored somehow. One option is to call std::cin.ignore() after the the first extraction. It will discard the next available character so that the newline is no longer intrusive.




    In-Depth Explanation:



    This is the overload of std::getline() that you called:




    template<class charT>
    std::basic_istream<charT>& getline( std::basic_istream<charT>& input,
    std::basic_string<charT>& str )



    Another overload of this function takes a delimiter of type charT. A delimiter character is a character that represents the boundary between sequences of input. This particular overload sets the delimiter to the newline character input.widen('n') by default since one was not supplied.



    Now, these are a few of the conditions whereby std::getline() terminates input:



    • If the stream has extracted the maximum amount of characters a std::basic_string<charT> can hold

    • If the end-of-file (EOF) character has been found

    • If the delimiter has been found

    The third condition is the one we're dealing with. Your input into state is represented thusly:




    "JohnnNew Hampshire"
    ^
    |
    next_pointer



    where next_pointer is the next character to be parsed. Since the character stored at the next position in the input sequence is the delimiter, std::getline() will quietly discard that character, increment next_pointer to the next available character, and stop input. This means that the rest of the characters that you have provided still remain in the buffer for the next I/O operation. You'll notice that if you perform another read from the line into state, your extraction will yield the correct result as the last call to std::getline() discarded the delimiter.




    You may have noticed that you don't typically run into this problem when extracting with the formatted input operator (operator>>()). This is because input streams use whitespace as delimiters for input and have the std::skipws1 manipulator set on by default. Streams will discard the leading whitespace from the stream when beginning to perform formatted input.2



    Unlike the formatted input operators, std::getline() is an unformatted input function. And all unformatted input functions have the following code somewhat in common:



    typename std::basic_istream<charT>::sentry ok(istream_object, true);


    The above is a sentry object which is instantiated in all formatted/unformatted I/O functions in a standard C++ implementation. Sentry objects are used for preparing the stream for I/O and determining whether or not it is in a fail state. You'll only find that in the unformatted input functions, the second argument to the sentry constructor is true. That argument means that leading whitespace will not be discarded from the beginning of the input sequence. Here is the relevant quote from the Standard [§27.7.2.1.3/2]:




     explicit sentry(basic_istream<charT, traits>& is, bool noskipws = false);


    [...] If noskipws is zero and is.flags() & ios_base::skipws is nonzero, the function extracts and discards each character as long as the next available input character c is a whitespace character. [...]




    Since the above condition is false, the sentry object will not discard the whitespace. The reason noskipws is set to true by this function is because the point of std::getline() is to read raw, unformatted characters into a std::basic_string<charT> object.




    The Solution:



    There's no way to stop this behavior of std::getline(). What you'll have to do is discard the new line yourself before std::getline() runs (but do it after the formatted extraction). This can be done by using ignore() to discard the rest of the input until we reach a fresh new line:



    if (std::cin >> name &&
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n') &&
    std::getline(std::cin, state))
    ...


    You'll need to include <limits> to use std::numeric_limits. std::basic_istream<...>::ignore() is a function that discards a specified amount of characters until it either finds a delimiter or reaches the end of the stream (ignore() also discards the delimiter if it finds it). The max() function returns the largest amount of characters that a stream can accept.



    Another way to discard the whitespace is to use the std::ws function which is a manipulator designed to extract and discard leading whitespace from the beginning of an input stream:



    if (std::cin >> name && std::getline(std::cin >> std::ws, state))
    ...


    What's the difference?



    The difference is that ignore(std::streamsize count = 1, int_type delim = Traits::eof())3 indiscriminately discards characters until it either discards count characters, finds the delimiter (specified by the second argument delim) or hits the end of the stream. std::ws is only used for discarding whitespace characters from the beginning of the stream.



    If you are mixing formatted input with unformatted input and you need to discard residual whitespace, use std::ws. Otherwise, if you need to clear out invalid input regardless of what it is, use ignore(). In our example, we only need to clear whitespace since the stream consumed your input of "John" for the name variable. All that was left was the newline character.




    1: std::skipws is manipulator that tells the input stream to discard leading whitespace when performing formatted input. This can be turned off with the std::noskipws manipulator.



    2: Input streams deem certain characters as whitespace by default, such the space character, newline character, form feed, carriage return, etc.



    3: This is the signature of std::basic_istream<...>::ignore(). You can call it with zero arguments to discard a single character from the stream, one argument to discard a certain amount of characters, or two arguments to discard count characters or until it reaches delim, whichever one comes first. You normally use std::numeric_limits<std::streamsize>::max() as the value of count if you don't know how many characters there are before the delimiter, but you want to discard them anyway.






    share|improve this answer















    Why does this happen?



    This has little to do with the input you provided yourself but rather with the default behavior std::getline() exhibits. When you provided your input for the name (std::cin >> name), you not only submitted the following characters, but also an implicit newline was appended to the stream:




    "Johnn"



    A newline is always appended to your input when you select Enter or Return when submitting from a terminal. It is also used in files for moving toward the next line. The newline is left in the buffer after the extraction into name until the next I/O operation where it is either discarded or consumed. When the flow of control reaches std::getline(), the newline will be discarded, but the input will cease immediately. The reason this happens is because the default functionality of this function dictates that it should (it attempts to read a line and stops when it finds a newline).



    Because this leading newline inhibits the expected functionality of your program, it follows that it must be skipped our ignored somehow. One option is to call std::cin.ignore() after the the first extraction. It will discard the next available character so that the newline is no longer intrusive.




    In-Depth Explanation:



    This is the overload of std::getline() that you called:




    template<class charT>
    std::basic_istream<charT>& getline( std::basic_istream<charT>& input,
    std::basic_string<charT>& str )



    Another overload of this function takes a delimiter of type charT. A delimiter character is a character that represents the boundary between sequences of input. This particular overload sets the delimiter to the newline character input.widen('n') by default since one was not supplied.



    Now, these are a few of the conditions whereby std::getline() terminates input:



    • If the stream has extracted the maximum amount of characters a std::basic_string<charT> can hold

    • If the end-of-file (EOF) character has been found

    • If the delimiter has been found

    The third condition is the one we're dealing with. Your input into state is represented thusly:




    "JohnnNew Hampshire"
    ^
    |
    next_pointer



    where next_pointer is the next character to be parsed. Since the character stored at the next position in the input sequence is the delimiter, std::getline() will quietly discard that character, increment next_pointer to the next available character, and stop input. This means that the rest of the characters that you have provided still remain in the buffer for the next I/O operation. You'll notice that if you perform another read from the line into state, your extraction will yield the correct result as the last call to std::getline() discarded the delimiter.




    You may have noticed that you don't typically run into this problem when extracting with the formatted input operator (operator>>()). This is because input streams use whitespace as delimiters for input and have the std::skipws1 manipulator set on by default. Streams will discard the leading whitespace from the stream when beginning to perform formatted input.2



    Unlike the formatted input operators, std::getline() is an unformatted input function. And all unformatted input functions have the following code somewhat in common:



    typename std::basic_istream<charT>::sentry ok(istream_object, true);


    The above is a sentry object which is instantiated in all formatted/unformatted I/O functions in a standard C++ implementation. Sentry objects are used for preparing the stream for I/O and determining whether or not it is in a fail state. You'll only find that in the unformatted input functions, the second argument to the sentry constructor is true. That argument means that leading whitespace will not be discarded from the beginning of the input sequence. Here is the relevant quote from the Standard [§27.7.2.1.3/2]:




     explicit sentry(basic_istream<charT, traits>& is, bool noskipws = false);


    [...] If noskipws is zero and is.flags() & ios_base::skipws is nonzero, the function extracts and discards each character as long as the next available input character c is a whitespace character. [...]




    Since the above condition is false, the sentry object will not discard the whitespace. The reason noskipws is set to true by this function is because the point of std::getline() is to read raw, unformatted characters into a std::basic_string<charT> object.




    The Solution:



    There's no way to stop this behavior of std::getline(). What you'll have to do is discard the new line yourself before std::getline() runs (but do it after the formatted extraction). This can be done by using ignore() to discard the rest of the input until we reach a fresh new line:



    if (std::cin >> name &&
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), 'n') &&
    std::getline(std::cin, state))
    ...


    You'll need to include <limits> to use std::numeric_limits. std::basic_istream<...>::ignore() is a function that discards a specified amount of characters until it either finds a delimiter or reaches the end of the stream (ignore() also discards the delimiter if it finds it). The max() function returns the largest amount of characters that a stream can accept.



    Another way to discard the whitespace is to use the std::ws function which is a manipulator designed to extract and discard leading whitespace from the beginning of an input stream:



    if (std::cin >> name && std::getline(std::cin >> std::ws, state))
    ...


    What's the difference?



    The difference is that ignore(std::streamsize count = 1, int_type delim = Traits::eof())3 indiscriminately discards characters until it either discards count characters, finds the delimiter (specified by the second argument delim) or hits the end of the stream. std::ws is only used for discarding whitespace characters from the beginning of the stream.



    If you are mixing formatted input with unformatted input and you need to discard residual whitespace, use std::ws. Otherwise, if you need to clear out invalid input regardless of what it is, use ignore(). In our example, we only need to clear whitespace since the stream consumed your input of "John" for the name variable. All that was left was the newline character.




    1: std::skipws is manipulator that tells the input stream to discard leading whitespace when performing formatted input. This can be turned off with the std::noskipws manipulator.



    2: Input streams deem certain characters as whitespace by default, such the space character, newline character, form feed, carriage return, etc.



    3: This is the signature of std::basic_istream<...>::ignore(). You can call it with zero arguments to discard a single character from the stream, one argument to discard a certain amount of characters, or two arguments to discard count characters or until it reaches delim, whichever one comes first. You normally use std::numeric_limits<std::streamsize>::max() as the value of count if you don't know how many characters there are before the delimiter, but you want to discard them anyway.







    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Aug 2 '16 at 3:56









    user -1

    556 bronze badges




    556 bronze badges










    answered Feb 5 '14 at 2:01









    0x499602D20x499602D2

    70.1k29 gold badges124 silver badges211 bronze badges




    70.1k29 gold badges124 silver badges211 bronze badges












    • Why not simply if (getline(std::cin, name) && getline(std::cin, state))?

      – Fred Larson
      Aug 19 '16 at 19:41











    • @FredLarson Good point. Though it wouldn't work if the first extraction is of an integer or anything that isn't a string.

      – 0x499602D2
      Aug 19 '16 at 20:30












    • Of course, that isn't the case here and there's no point in doing the same thing two different ways. For an integer you could get the line into a string and then use std::stoi(), but then it's not so clear there's an advantage. But I tend to prefer to just use std::getline() for line-oriented input and then deal with parsing the line in whatever way makes sense. I think it's less error prone.

      – Fred Larson
      Aug 19 '16 at 20:35











    • @FredLarson Agreed. Maybe I'll add that in if I have the time.

      – 0x499602D2
      Aug 19 '16 at 20:39

















    • Why not simply if (getline(std::cin, name) && getline(std::cin, state))?

      – Fred Larson
      Aug 19 '16 at 19:41











    • @FredLarson Good point. Though it wouldn't work if the first extraction is of an integer or anything that isn't a string.

      – 0x499602D2
      Aug 19 '16 at 20:30












    • Of course, that isn't the case here and there's no point in doing the same thing two different ways. For an integer you could get the line into a string and then use std::stoi(), but then it's not so clear there's an advantage. But I tend to prefer to just use std::getline() for line-oriented input and then deal with parsing the line in whatever way makes sense. I think it's less error prone.

      – Fred Larson
      Aug 19 '16 at 20:35











    • @FredLarson Agreed. Maybe I'll add that in if I have the time.

      – 0x499602D2
      Aug 19 '16 at 20:39
















    Why not simply if (getline(std::cin, name) && getline(std::cin, state))?

    – Fred Larson
    Aug 19 '16 at 19:41





    Why not simply if (getline(std::cin, name) && getline(std::cin, state))?

    – Fred Larson
    Aug 19 '16 at 19:41













    @FredLarson Good point. Though it wouldn't work if the first extraction is of an integer or anything that isn't a string.

    – 0x499602D2
    Aug 19 '16 at 20:30






    @FredLarson Good point. Though it wouldn't work if the first extraction is of an integer or anything that isn't a string.

    – 0x499602D2
    Aug 19 '16 at 20:30














    Of course, that isn't the case here and there's no point in doing the same thing two different ways. For an integer you could get the line into a string and then use std::stoi(), but then it's not so clear there's an advantage. But I tend to prefer to just use std::getline() for line-oriented input and then deal with parsing the line in whatever way makes sense. I think it's less error prone.

    – Fred Larson
    Aug 19 '16 at 20:35





    Of course, that isn't the case here and there's no point in doing the same thing two different ways. For an integer you could get the line into a string and then use std::stoi(), but then it's not so clear there's an advantage. But I tend to prefer to just use std::getline() for line-oriented input and then deal with parsing the line in whatever way makes sense. I think it's less error prone.

    – Fred Larson
    Aug 19 '16 at 20:35













    @FredLarson Agreed. Maybe I'll add that in if I have the time.

    – 0x499602D2
    Aug 19 '16 at 20:39





    @FredLarson Agreed. Maybe I'll add that in if I have the time.

    – 0x499602D2
    Aug 19 '16 at 20:39













    10














    Everything will be OK if you change your initial code in the following way:



    if ((cin >> name).get() && std::getline(cin, state))





    share|improve this answer




















    • 2





      Thank you. This will also work because get() consumes the next character. There's also (std::cin >> name).ignore() which I suggested earlier in my answer.

      – 0x499602D2
      Mar 26 '14 at 12:14











    • "..work because get()..." Yes, exactly. Sorry for giving the answer without details.

      – Boris
      Mar 26 '14 at 13:14







    • 4





      Why not simply if (getline(std::cin, name) && getline(std::cin, state))?

      – Fred Larson
      Aug 19 '16 at 19:41















    10














    Everything will be OK if you change your initial code in the following way:



    if ((cin >> name).get() && std::getline(cin, state))





    share|improve this answer




















    • 2





      Thank you. This will also work because get() consumes the next character. There's also (std::cin >> name).ignore() which I suggested earlier in my answer.

      – 0x499602D2
      Mar 26 '14 at 12:14











    • "..work because get()..." Yes, exactly. Sorry for giving the answer without details.

      – Boris
      Mar 26 '14 at 13:14







    • 4





      Why not simply if (getline(std::cin, name) && getline(std::cin, state))?

      – Fred Larson
      Aug 19 '16 at 19:41













    10












    10








    10







    Everything will be OK if you change your initial code in the following way:



    if ((cin >> name).get() && std::getline(cin, state))





    share|improve this answer















    Everything will be OK if you change your initial code in the following way:



    if ((cin >> name).get() && std::getline(cin, state))






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Mar 26 '14 at 12:21









    Qantas 94 Heavy

    12.4k15 gold badges56 silver badges74 bronze badges




    12.4k15 gold badges56 silver badges74 bronze badges










    answered Mar 26 '14 at 12:01









    BorisBoris

    1564 bronze badges




    1564 bronze badges







    • 2





      Thank you. This will also work because get() consumes the next character. There's also (std::cin >> name).ignore() which I suggested earlier in my answer.

      – 0x499602D2
      Mar 26 '14 at 12:14











    • "..work because get()..." Yes, exactly. Sorry for giving the answer without details.

      – Boris
      Mar 26 '14 at 13:14







    • 4





      Why not simply if (getline(std::cin, name) && getline(std::cin, state))?

      – Fred Larson
      Aug 19 '16 at 19:41












    • 2





      Thank you. This will also work because get() consumes the next character. There's also (std::cin >> name).ignore() which I suggested earlier in my answer.

      – 0x499602D2
      Mar 26 '14 at 12:14











    • "..work because get()..." Yes, exactly. Sorry for giving the answer without details.

      – Boris
      Mar 26 '14 at 13:14







    • 4





      Why not simply if (getline(std::cin, name) && getline(std::cin, state))?

      – Fred Larson
      Aug 19 '16 at 19:41







    2




    2





    Thank you. This will also work because get() consumes the next character. There's also (std::cin >> name).ignore() which I suggested earlier in my answer.

    – 0x499602D2
    Mar 26 '14 at 12:14





    Thank you. This will also work because get() consumes the next character. There's also (std::cin >> name).ignore() which I suggested earlier in my answer.

    – 0x499602D2
    Mar 26 '14 at 12:14













    "..work because get()..." Yes, exactly. Sorry for giving the answer without details.

    – Boris
    Mar 26 '14 at 13:14






    "..work because get()..." Yes, exactly. Sorry for giving the answer without details.

    – Boris
    Mar 26 '14 at 13:14





    4




    4





    Why not simply if (getline(std::cin, name) && getline(std::cin, state))?

    – Fred Larson
    Aug 19 '16 at 19:41





    Why not simply if (getline(std::cin, name) && getline(std::cin, state))?

    – Fred Larson
    Aug 19 '16 at 19:41











    0














    This happens because an implicit line feed also known as newline character n is appended to all user input from a terminal as it's telling the stream to start a new line. You can safely account for this by using std::getline when checking for multiple lines of user input. The default behavior of std::getline will read everything up to and including the newline character n from the input stream object which is std::cin in this case.



    #include <iostream>
    #include <string>

    int main()

    std::string name;
    std::string state;

    if (std::getline(std::cin, name) && std::getline(std::cin, state))

    std::cout << "Your name is " << name << " and you live in " << state;

    return 0;




    Input:

    "John"
    "New Hampshire"

    Output:

    "Your name is John and you live in New Hampshire"






    share|improve this answer





























      0














      This happens because an implicit line feed also known as newline character n is appended to all user input from a terminal as it's telling the stream to start a new line. You can safely account for this by using std::getline when checking for multiple lines of user input. The default behavior of std::getline will read everything up to and including the newline character n from the input stream object which is std::cin in this case.



      #include <iostream>
      #include <string>

      int main()

      std::string name;
      std::string state;

      if (std::getline(std::cin, name) && std::getline(std::cin, state))

      std::cout << "Your name is " << name << " and you live in " << state;

      return 0;




      Input:

      "John"
      "New Hampshire"

      Output:

      "Your name is John and you live in New Hampshire"






      share|improve this answer



























        0












        0








        0







        This happens because an implicit line feed also known as newline character n is appended to all user input from a terminal as it's telling the stream to start a new line. You can safely account for this by using std::getline when checking for multiple lines of user input. The default behavior of std::getline will read everything up to and including the newline character n from the input stream object which is std::cin in this case.



        #include <iostream>
        #include <string>

        int main()

        std::string name;
        std::string state;

        if (std::getline(std::cin, name) && std::getline(std::cin, state))

        std::cout << "Your name is " << name << " and you live in " << state;

        return 0;




        Input:

        "John"
        "New Hampshire"

        Output:

        "Your name is John and you live in New Hampshire"






        share|improve this answer















        This happens because an implicit line feed also known as newline character n is appended to all user input from a terminal as it's telling the stream to start a new line. You can safely account for this by using std::getline when checking for multiple lines of user input. The default behavior of std::getline will read everything up to and including the newline character n from the input stream object which is std::cin in this case.



        #include <iostream>
        #include <string>

        int main()

        std::string name;
        std::string state;

        if (std::getline(std::cin, name) && std::getline(std::cin, state))

        std::cout << "Your name is " << name << " and you live in " << state;

        return 0;




        Input:

        "John"
        "New Hampshire"

        Output:

        "Your name is John and you live in New Hampshire"







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Feb 21 '18 at 1:19

























        answered Feb 21 '18 at 0:46









        Justin RandallJustin Randall

        1,6912 gold badges10 silver badges12 bronze badges




        1,6912 gold badges10 silver badges12 bronze badges















            protected by StoryTeller Dec 6 '17 at 8:53



            Thank you for your interest in this question.
            Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).



            Would you like to answer one of these unanswered questions instead?



            Popular posts from this blog

            Kamusi Yaliyomo Aina za kamusi | Muundo wa kamusi | Faida za kamusi | Dhima ya picha katika kamusi | Marejeo | Tazama pia | Viungo vya nje | UrambazajiKuhusu kamusiGo-SwahiliWiki-KamusiKamusi ya Kiswahili na Kiingerezakuihariri na kuongeza habari

            Swift 4 - func physicsWorld not invoked on collision? The Next CEO of Stack OverflowHow to call Objective-C code from Swift#ifdef replacement in the Swift language@selector() in Swift?#pragma mark in Swift?Swift for loop: for index, element in array?dispatch_after - GCD in Swift?Swift Beta performance: sorting arraysSplit a String into an array in Swift?The use of Swift 3 @objc inference in Swift 4 mode is deprecated?How to optimize UITableViewCell, because my UITableView lags

            Access current req object everywhere in Node.js ExpressWhy are global variables considered bad practice? (node.js)Using req & res across functionsHow do I get the path to the current script with Node.js?What is Node.js' Connect, Express and “middleware”?Node.js w/ express error handling in callbackHow to access the GET parameters after “?” in Express?Modify Node.js req object parametersAccess “app” variable inside of ExpressJS/ConnectJS middleware?Node.js Express app - request objectAngular Http Module considered middleware?Session variables in ExpressJSAdd properties to the req object in expressjs with Typescript