I know there are a bunch of threads on this already, but I'm having a tiny bit of trouble understanding them. Anyways, there's a well-known glitch/error/bug (more of a beginner's mistake) that, when the wrong kind of data's entered into the command line (such as a char when an int was expected), will result in a sort of infinite looping, repeatedly prompting for input and not waiting for a response. I was unable to reproduce this, despite trying.
So when does it occur, and how could one prevent it?
Let's say you have an int input, and stick in some string of characters. It'll happen then. You can prevent it by checking for flags of your input stream, or by doing something like
1 2 3
If(cin >> input)
something = input;
What this does is checks to see if the input was valid before doing anything with it. There's a little more to it, and you can look it up if your curious, but that'll work
#include <iostream>
int main()
{
while(true)
{
int a,b;
char operation;
std::cout << "\nEnter a single operation\n" << std::endl;
if (std::cin >> a)
{
std::cin >> operation;
if (std::cin >> b)
{
switch (operation)
{
case ('+'):
std::cout << a+b << std::endl;
break;
case ('-'):
std::cout << a-b << std::endl;
break;
case ('*'):
std::cout << a*b << std::endl;
break;
case ('/'):
std::cout << static_cast<double>(a)/static_cast<double>(b) << std::endl;
break;
default:
std::cout << "You entered an invalid operation." << std::endl;
}
}
else
{
std::cout << "You entered it wrong. Do it right this time." << std::endl;
}
}
else
{
std::cout << "You entered it wrong. Do it right this time." << std::endl;
}
}
}
There's a little more to it, and you can look it up if your curious, but that'll work
When you input something cin doesn't like, you break the cin. You have to fix it:
1 2 3 4 5
while (!(cin >> a)) // While the input is breaking the cin
cin.clear(); // Reset the state of the cin object
cin.sync(); // clear the buffer, else there could still be something there to break it again
cout << "You messed up. Try again: ";
}
This might take some figuring to get it working for your program, but the method is the same. Maybe you don't want the actual extraction in the condition, etc.
#include <iostream>
int main()
{
while (true)
{
int a,b;
char operation;
std::cout << "\nEnter an operation\n" << std::endl;
if (!(std::cin >> a))
{
std::cout << "You entered it wrong. Get it right next time." << std::endl;
std::cin.clear();
std::cin.sync();
continue;
}
std::cin >> operation;
if (!(std::cin >> b))
{
std::cout << "You entered it wrong. Get it right next time." << std::endl;
std::cin.clear();
std::cin.sync();
continue;
}
switch (operation)
{
case ('+'):
std::cout << a+b << std::endl;
break;
case ('-'):
std::cout << a-b << std::endl;
break;
case ('*'):
std::cout << a*b << std::endl;
break;
case ('/'):
std::cout << static_cast<double>(a)/static_cast<double>(b) << std::endl;
break;
default:
std::cout << "You entered an invalid operation." << std::endl;
}
}
}
Replacing those if's with while's just resulted in that while being an infinite loop. I'm obviously getting the whole idea of this wrong somehow, but what am I doing wrong?
#include <iostream>
int main()
{
while (true)
{
int a,b;
char operation;
bool caught = false;;
std::cout << "\nEnter an operation\n" << std::endl;
if (!(std::cin >> a))
{
while (!(std::cin))
{
std::cin.clear();
std::cin.sync();
}
std::cout << "You entered it wrong. Get it right next time." << std::endl;
caught = true;
}
std::cin >> operation;
if (!(std::cin >> b))
{
while (!(std::cin))
{
std::cin.clear();
std::cin.sync();
}
if (!caught)
{
std::cout << "You entered it wrong. Get it right next time." << std::endl;
}
caught = true;
}
switch (operation)
{
case ('+'):
std::cout << a+b << std::endl;
break;
case ('-'):
std::cout << a-b << std::endl;
break;
case ('*'):
std::cout << a*b << std::endl;
break;
case ('/'):
std::cout << static_cast<double>(a)/static_cast<double>(b) << std::endl;
break;
default:
if (!caught)
{
std::cout << "You entered an invalid operation." << std::endl;
}
}
}
}
It at least manages to stop, but it doesn't seem to want to output any operations afterwards, and it takes a lot of iterations to stop. Here was the input/output from one of the times I ran this.