• 0

c++ BUG ?!


Question

Well, I was just playing with C++ and made a trivial program:

int user_num;
while(true)
{
	cin>>user_num;
	cout<<(int)user_num<<'\n';
}

Weird thing is, if the user enters non-integer number, the program keeps repeating the integer number forever.

For example: if user enter 8.1, program will keep repeating 8 in an infinite loop.But if he entered integer number, it will just show the number normally and wait for next number.

Tried to change that, instead (int) made it (bool), and similar thing happenned, if user enter any non-zero non-integer number, the program keeps repeating 1 forever.But if integer number it will converted to 1 normally (or 0 if user entered 0).

I tried also to make it (bool)(int)user_num but same thing.

Got it fixed when I changed user_num type to float, but why the error happened in the first place ? just curious if anybody can explain.

OS: Win XP SP3

Compiler: VC++ 6

post-278218-12643902662049_thumb.jpg

Link to comment
Share on other sites

16 answers to this question

Recommended Posts

  • 0

while(true) {
...
}

Will loop forever because the conditional is "true". Change "true" to your variable.

The thing is, it doesn't wait for user input at cin when you enter a float. This is quite strange.

Link to comment
Share on other sites

  • 0

So you create an infinite loop and wonder why it loops infinitely?

The loop is infinite, but what it does inifnitly is:

wait for user input

convert to integer and show it

wait for other input

NOT:

wait for user input

convert to integer

keep repeating the converted value forever and not wait for other input !

This is the thing am wondering why it happened.

Link to comment
Share on other sites

  • 0

Found some more info at http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.2

In particular, if someone enters something that doesn't look like an integer (such as an 'x'), the stream std::cin goes into a "failed state," and all subsequent input attempts return immediately without doing anything
Edited by TheWiseIstari
Link to comment
Share on other sites

  • 0

I would venture to guess it has to do with the way cin works. When you type "8.1" and hit enter, the "8" gets stored while the ".1" sits in the stream. The next iteration comes around and it sees ".1" in the stream and ignores it because it's not an int. It then print out user_num and begins again.

Try cin'ing a string and then casting it to an int.

Edited by CentralDogma
Link to comment
Share on other sites

  • 0

Found some more info at http://www.parashift...t.html#faq-15.2

thanks :)

that explains it

Fixed the code, now it is:

float user_num;
while(!cin.fail())
{
	cin>>user_num;
	cout<<(int)user_num<<'\n';
}

float will prevent errors when converting decimals, and the while(!cin.fail()) should prevent errors if user enter any other data type.

Link to comment
Share on other sites

  • 0

float will prevent errors when converting decimals, and the while(!cin.fail()) should prevent errors if user enter any other data type.

Glad it helped. I only started learning c++ a few days ago, and stuff like this is good to know.

Link to comment
Share on other sites

  • 0

It works, but it's not flexible. If you try validate anything more complex than a single input, taking the whole line as a string and then processing that string makes much more sense. See http://www.fredosaurus.com/notes-cpp/strings/stringstream-example.html for instance.

I'm not quite sure what you mean. My code was more to demonstrate that the issue was the stream, it's not really ment to be a practical solution to any problem. I certainly wouldn't use it in production code because I would imagine clear() and sync() are far more "costly" then storing as a string and casting.

Link to comment
Share on other sites

  • 0

I thought the best way to check if the stream was in a valid state was just to rely on its operator void*().

So the following code would be best:

int user_num;
while ( std::cin >> user_num )
{
    std::cout << user_num << std::endl;
}

Link to comment
Share on other sites

  • 0

I thought the best way to check if the stream was in a valid state was just to rely on its operator void*().

So the following code would be best:

int user_num;
while ( std::cin >> user_num )
{
    std::cout << user_num << std::endl;
}

That would stop the loop on invalid input. If you wanted to just ignore invalid input, you would have to use one of the other methods.

Link to comment
Share on other sites

  • 0

I'm not quite sure what you mean. My code was more to demonstrate that the issue was the stream, it's not really ment to be a practical solution to any problem. I certainly wouldn't use it in production code because I would imagine clear() and sync() are far more "costly" then storing as a string and casting.

We agree, I must have misunderstood you. NVM.
Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.