Effect of noskipws on cin>>
Asked Answered
S

1

8

As I understand, the extraction operator skips the whitespace in the beginning and stops upon encountering a whitespace or end of stream. noskipws can be used to stop ignoring the leading whitespaces.

I have the following program where I have used noskipws.

#include <iostream>
using namespace std;

int main()
{
    char name[128];

    cout<<"Enter a name ";
    cin>>noskipws>>name;
    cout<<"You entered "<<name<<"\n";

    cout<<"Enter another name ";
    cin>>name;
    cout<<"You entered "<<(int)name[0]<<"\n";

    return 0;
}

My queries are:

  1. If I enter "John" as the first input, then the second cin>> operation does not wait for input and does not copy anything to the destination i.e. the name array. I expected second cin>> to transfer at-least a newline or end of stream, instead of just setting the destination string to empty. Why is this happening ?

  2. The same thing is observed when I enter "John Smith" as the input for first cin>> statement. Why doesn't the second cin>> statement copy the space or "Smith" to the destination variable ?

Following is the output of the program:

Enter a name John
You entered John
Enter another name You entered 0


Enter a name John Smith
You entered John
Enter another name You entered 0

Thanks!!!

Sideburns answered 8/6, 2012 at 10:3 Comment(2)
I hope you know that you program can produce buffer overflows very easily. In production code, you should not use std::cin to write into a char array. Use a std::string instead.Patinated
Thats true. The above code was for illustration purposes only. Using cin.width or cin.getline can avoid some of the overflow issues, but as you mentioned std::string would be best. I gave the above example code just to show what I was trying to ask.Sideburns
A
14

The basic algorithm for >> of a string is:

skip whitespace
read and extract until next whitespace

If you use noskipws, then the first step is skipped. After the first read, you are positionned on a whitespace, so the next (and all following) reads will stop immediatly, extracting nothing.

>> to a string will never put whitespace into the string. More generally, using >> with noskipws is problematic, since whitespace is always a separator for >>; it may make sense to use it punctually, but it should generally be reset immediately after it has been used. (The once case where it might make sense is when using >> to a char. In this case, the stream always extracts one character.)

Argil answered 8/6, 2012 at 10:13 Comment(2)
Okay got your point. But I am stil confused as to why didn't input of "John Smith" cause the >> operator to copy "Smith" in the second input operation. Why did "Smith" disappear from the input stream completely and even then the second cin operation did not wait for an input.Sideburns
@AchintMehta Because the next character to be read is a white space, not the S in "Smith". You told it not to skip the whitespace, so it doesn't. It then inputs up to but not including the next whitespace, which is immediate. The "Smith" doesn't disappear, you just don't read it. And you can't read it with >>, except >> into a char, since all of the other >> will stop at the first whitespace, extracting nothing, and not advancing the input position.Argil

© 2022 - 2024 — McMap. All rights reserved.