int x;
while(cin>>x)
{
cout<<"Yes"<<endl;
}
int y;
while(cin>>y)
{
cout<<"Yes again"<<endl;
}

What I expected to happen is,that as long as I entered a number for x(in line 2)that block should be run and "Yes" must be printed.
To get out of the 1st while loop I enter some char like 'h' and the same thing applies with the second while loop.
But what happens is when I enter 'h' both the loops break and the program ends.
Why does this happen?

Recommended Answers

All 17 Replies

In the first while loop your exit condition is when cin fails. It will fail when it reads in something that its no supposed to. Its expecting a integer( a number ), and if you pass it a character, then cin fails and it sets the failure bits accordingly.

Now in your second loop, cin is still in a fail state because you haven't reset the cin stream, thus the failure bits are still set and thats why it doesn't execute. To solve your problem, you need to reset the input stream.

int x = 0 ;
while( cin >> x) { cout << "read : " << x << endl; }
//if we are here, then cin failed so we need to reset the stream
cin.clear(); //clear or reset the failure bits
while( cin.get() != '\n' ); // throw away any junk that is in the stream after failure
int y = 0;
//now cin is reseted so use it normally
while( cin >> y ){ cout << "read : " << y << endl; }

whats this supposed to do:

while( cin.get() != '\n' );

there isn't a body for the while loop.

whats this supposed to do:

while( cin.get() != '\n' );

there isn't a body for the while loop.

cin.get() extracts a character from the stream and returns its value (casted to an integer). Given that, the above code you've posted is supposed to exit when you hit enter even if you typed anything else before hitting enter.

For example, if you typed in the following text then hit enter:

example

cin.get() would firstly return the ASCII code of the character 'e' which is not equal to '\n', so the loop will be executed again and cin.get() would return the ASCII code of the character 'x' which is also not equal to '\n', and the loop keeps executing till cin.get() returns 10 which is the ASCII code for '\n' (the new line resulting form hitting Enter).

NOTE the semicolon ; at the end of the while statement.
istream::get: http://cplusplus.com/reference/iostream/istream/get/

Cheers,
Kimo :)

whats this supposed to do:

while( cin.get() != '\n' );

there isn't a body for the while loop.

it reads the stream character by character but doesn't save the read character, it just does nothing with the read character, if we wanted to save the character, we could have done this :

char ch = 0;
while( cin.get(ch) && ch != '\n') { 
 //do something with ch variable, which contains the read junk character
}

No I am confused.
Lets say I entered 'h' in my first program,the first time.
That obviously won't go into x and failure bits are set.

Now we come out of the 1st while loop and it is time to clear out the stream.
like this

cin.clear();

now,

while( cin.get() != '\n' );

what does get() get,.....now that the stream is completely cleared?
I(user) have no interaction with the program as I am not prompted to an input yet.
next cin is still some lines away?
1.Now how will the cin.get() get a '\n' when I am not hitting any enter button?
I am not typing in anything yet.
2.How does the while loop(given by firstPerson) end?
Does the get() function progress through the characters?

int x;
while(cin>>x)
{
cout<<"Yes"<<endl;
}
int y;
while(cin>>y)
{
cout<<"Yes again"<<endl;
}

.....
Variable x and y ar4e integer type there and you pass the value to these variable that was character type so please pass the integer value to variable x and y, not pass h to x and y because h is character

No I am confused.
now,

while( cin.get() != '\n' );

what does get() get,.....now that the stream is completely cleared?
I(user) have no interaction with the program as I am not prompted to an input yet.
next cin is still some lines away?
1.Now how will the cin.get() get a '\n' when I am not hitting any enter button?
I am not typing in anything yet.
2.How does the while loop(given by firstPerson) end?
Does the get() function progress through the characters?

cin.clear() clears all error flags, but it doesn't discard the characters in the stream.
so you have to put this line of code after clearing the error flags to remove or ignore any characters in the stream:

while(cin.get() != '\n');

You can also use cin.ignore() as in the following code:

int x = 0;
while(cin >> x)
{
    cout << "read: " << x << endl;
}
// If we are here, then cin failed so we need to reset the stream.
cin.clear(); // Clear or reset the failure bits.
cin.ignore(numeric_limits<streamsize>::max(), '\n'); /*  Throw away any junk that is in the stream after failure. */
int y = 0;
//now cin is reseted so use it normally
while( cin >> y )
{
    cout << "read: " << y << endl;
}

You have to include <limits> in your program to be able to use numeric_limits.
More information about cin.ignore():
http://cplusplus.com/reference/iostream/istream/ignore/

More information about numeric_limits:
http://cplusplus.com/reference/std/limits/numeric_limits/

just look at what it gets and you'll see:

int x = 0;
while(cin >> x) { continue;}
cin.clear();
//discard junk and print out whats being discarded:
char ch = 0;
while(cin.get(ch) && ch != '\n') cout << "Discarding'" << ch << "'" << endl;

Okay.
SO there are 2 things to be done.
1.Reset the failure bits.
2.Throw away the existing characters in the stream.
Both of these have to done to use the cin again.Correct?
But suppose I entered a good value(a number) here:

int y;
cin>>y;

Now the failure bits aren't set.But shouldn't I clear out the input stream before I use cin again?But I have seen it work without that done.

and,
I didn't expect this to compile,but it did,and gave me something expected:

int x;
cin>>x;
cin.clear();
while(cin.get()){continue;}
//since cin.get() returns an int,what sense does the while condition make?

since cin.get() returns an int,what sense does the while condition make?

and also,when I entered 'h' for x,the while loop ran twice,collecting the 'h' and '\n',but after that,I was again prompted to enter something.
Why so?What is happening?

And also,why have you used the condition,while(cin.get()!='\n')?
Is there a problem if the '\n' is collected from the stream?Whats the harm?

That is the wrong way to go about clearing the keyboard input buffer. Narue has written an excellent article about that very topic. See this link

But shouldn't I clear out the input stream before I use cin again?

How do you know that it needs to be cleared? What if the next request for input corresponds to whatever is already in the stream? I can type "123 4.5 booga" all on one line and the following code will work perfectly:

#include <iostream>
#include <string>

int main()
{
    int a;
    double b;
    std::string c;

    std::cin>> a;
    std::cin>> b;
    std::cin>> c;
    std::cout<< a <<'\n'<< b <<'\n'<< c <<'\n';
}

There's no need to clear the stream when it's properly formatted in the first place.

since cin.get() returns an int,what sense does the while condition make?

The condition is equiavelent to while (cin.get() != 0) . However, since it's rather difficult to get cin.get() to return 0, that loop is nonsensical.

and also,when I entered 'h' for x,the while loop ran twice,collecting the 'h' and '\n',but after that,I was again prompted to enter something.
Why so?What is happening?

How did you plan on typing a character with the value 0?

And also,why have you used the condition,while(cin.get()!='\n')?
Is there a problem if the '\n' is collected from the stream?Whats the harm?

That method of clearing the stream relies in line-oriented interactive input. The user will never enter more than a single line at a time, so when you detect a newline character it corresponds to the end of input. Trying to read further would block for more input and defeat the purpose of "clearing the stream".

How do you know that it needs to be cleared? What if the next request for input corresponds to whatever is already in the stream? I can type "123 4.5 booga" all on one line and the following code will work perfectly:

No that isn't what I asked.
Suppose I did:

int x;
cin>>x;
int y;
cin>>y;

Now when I enter '5' the first time,'5' gets filled in the input stream.Then x takes the value 5.Now shouldn't I clear out the stream again,before I use it to take another input?
What I thought was,with the above code,there won't be a second prompt for input,because,the '5' I entered is already lying in the stream and y will also be given the same value.But it isn't so.Why?

The condition is equiavelent to while (cin.get() != 0) . However, since it's rather difficult to get cin.get() to return 0, that loop is nonsensical.

cin.get() extracts characters from the stream.But if it is empty does it ask for another one from the user?
Is that why the loop keeps asking me to enter something?

What I thought was,with the above code,there won't be a second prompt for input,because,the '5' I entered is already lying in the stream and y will also be given the same value.But it isn't so.Why?

When you successfully read a value from the stream, that value is removed from the stream.

cin.get() extracts characters from the stream.But if it is empty does it ask for another one from the user?

It waits for further input, yes.

OP probably won't understand this completely right now, but just for giggles here is a generic approach-ish.

#include <iostream>
#include <sstream>
#include <string>
using namespace std;


//Used to convert between types
template<typename S,typename T>
struct SStreamConverter{
 S operator()(const T& in)const{ 
    stringstream ss; 
    S ret = S(); 
    if( !( (ss << in) && (ss >> ret) ) ) throw std::exception();
    else return ret;
 }
};

//used to check if a input is a valid type
template<typename T>
struct IsType{
	template<typename InputType>
	bool operator()(const InputType& s)const{
		std::istringstream stream(s);
		T instance;
		return ((stream >> instance) && (stream >> std::ws) && stream.eof());
	}
};

//An exception representing invalid input error
struct InvalidInputException : std::exception{
	InvalidInputException(): std::exception("Error: Invalid input detected")  {}
	InvalidInputException(const std::string& errorMsg): std::exception(errorMsg.c_str()){}
};

//An Input Grabber from the stream
template<typename T,typename Validator = IsType<T>, typename Converter = SStreamConverter<T,std::string> >
class Streamer{
private:
	Validator isValid;
	Converter convertTo;
public:
	//tries to get the input once	
	T get(istream& stream = cin)const{
		std::string input;
		T result = T();
		getline(stream, input );
		//check for valid input
		if(!(isValid(input)) ) throw InvalidInputException();
		try{ result = convertTo(input); }
		catch(std::exception&){ throw InvalidInputException(); }
		return result; //return if everyting if good
	}
	//tries to get the input until a valid once is detected
	T getUntil(const std::string& errorMsg = "Invalid Input detected, try again\n",istream& stream = cin)const{
		T result = T();
		bool validResult = true;
		do{
			try{
				result = get(stream);
				validResult = true;
			}catch(std::exception&){ 
				validResult = false; 
				cout << errorMsg;
			}
		}while(!validResult);
		return result;
	}
};

int main(){
 Streamer<float> streamer; 
 try{
	 float num = streamer.get();
	cout << "Your number is " << num << endl;
 }catch(std::exception& e){
	 cout << e.what() << endl;
 }

}

Note I say generic-ish because one fault it has is that a streamer has to be created for each type. To better it, you may remove this restriction somehow.

just for giggles here is a generic approach-ish

Hmm, overkill maybe? That whole process can be accomplished with a non-member function, and the approach can be made fully generic (for types that support operator>>) with argument type deduction:

#include <iostream>
#include <istream>
#include <sstream>
#include <string>

template <typename T>
bool get_next(T& value, std::istream& in = std::cin)
{
    std::string line;

    try {
        if (std::getline(in, line)) {
            std::istringstream iss(line);

            if (iss>> value >> std::ws && iss.eof())
                return true;
        }
    } catch (...) {
        // Collect all exceptions into a failure result
    }

    return false;
}

int main()
{
    float num;

    while (!get_next(num))
        std::cerr<<"Invalid input, please try again: ";

    std::cout<<"Your number is "<< num <<'\n';
}

The problem, of course, is your assumption that there's one item of input for each line. You'll find that as you adjust the solution to allow multiple items per line, it begins to look more and more like how the standard library does things. ;)

Hmm, overkill maybe? That whole process can be accomplished with a non-member function, and the approach can be made fully generic (for types that support operator>>) with argument type deduction:

#include <iostream>
#include <istream>
#include <sstream>
#include <string>

template <typename T>
bool get_next(T& value, std::istream& in = std::cin)
{
    std::string line;

    try {
        if (std::getline(in, line)) {
            std::istringstream iss(line);

            if (iss>> value >> std::ws && iss.eof())
                return true;
        }
    } catch (...) {
        // Collect all exceptions into a failure result
    }

    return false;
}

int main()
{
    float num;

    while (!get_next(num))
        std::cerr<<"Invalid input, please try again: ";

    std::cout<<"Your number is "<< num <<'\n';
}

The problem, of course, is your assumption that there's one item of input for each line. You'll find that as you adjust the solution to allow multiple items per line, it begins to look more and more like how the standard library does things. ;)

Yea I know, buts its no fun when the answer is simple :(

Thank You all.I didn't understand the last 3 posts but.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.