Uzair Zia
Uzair Zia

Reputation: 53

Why is cin.ignore() necessary when using "getline" after "cin", but is not required when using "cin" multiple times?

In my knowledge when using getline() after cin, we need to flush the newline character in the buffer first, before calling getline(), and we do this by calling cin.ignore().

std::string name, address;

std::cin >> name;
std::cin.ignore(); //flush newline character
getline(std::cin,address);

But when using multiple cin, we do not need to flush the newline character.

std::string firstname, lastname;

std::cin >> firstname;
std::cout << firstname << std::endl;

//no need to flush newline character

std::cin >> lastname;
std::cout << lastname << std::endl;

Why is that? Why is cin.ignore() necessary in the first case, but not the last?

Upvotes: 4

Views: 9099

Answers (2)

srbcheema1
srbcheema1

Reputation: 618

signed main(){
    /*
     * input is of next two lines
     * Stack Overflow<Enter>
     * Where developers learn.<Enter>
     * for more about cin.ignore visit http://www.cplusplus.com/reference/istream/istream/ignore/
     */
    string name, address;
    cin>>name;
    //cin.ignore();
    //cin.ignore(256,'\n');
    getline(cin,address);
    cout << address << endl;
    assert(address == " Overflow"); // breaks if using cin.ignore() or cin.ignore(256,'\n')
    assert(address == "Overflow"); // breaks if using cin.ignore(256,'\n') OR not using any
    assert(address == "Where developers learn."); // breaks if using cin.ignore() or not using ignore
}

enter the input

Stack Overflow

Where developers learn.

Upvotes: 0

iBug
iBug

Reputation: 37327

Because getline() reads until the next newline character from the given std::istream, while std::istream::operator>>() skips any whitespaces (Spaces, Tabs and newlines).

So when you read an integer or a floating point number, all trailing whitespaces are left in the input stream. When you read from a console or terminal, you type the data and hit Enter, the latter of which is left in the stream, and will be caught by getline() if you don't clear it.

You don't have to clear it because the next time you read a std::string, std::istream::operator>>() skips the whitespaces for you.


Consider this code segment;

std::string a, b;
std::cin >> a;
std::getline(std::cin, b);

and this input:

Stack Overflow<Enter>
Where developers learn.<Enter>

The first cin statement will read the word Stack, leaving a space and Overflow<Enter> behind. Then it'll be read by getline, so

assert(b == " Overflow");

If you insert a std::cin.ignore() before calling getline(), it will instead turn into

assert(b == "Where developers learn.");

Upvotes: 4

Related Questions