Getting numerical input (long post)

Started by
1 comment, last by Conner McCloud 18 years, 8 months ago
Hi, Here's more trouble I'm having. It's again a problem with checking to see whether or not an integer has been entered, and how to deal with it. I've tried advice taken from an earlier thread of mine (retired now), and also that page Zahlman finds useful. It's still a lottery simulator I'm trying to do. But I'm having trouble determining whether or not the supplied input is an integer or not. Here's the relevant code I have at the moment:

#include <iostream>
#include <iomanip>
#include <ctime>
#include <cstdlib>
#include <list>
#include <limits>
#include <string>

std::list<int> InputNumbers; // Player input numbers
std::list<int>::iterator InputCounter; // Player's list iterator

void GetNumbers()
{

	int Input;

	while(InputNumbers.size()<6)
	{

		int Remaining=6-InputNumbers.size();

		std::cout<<std::setw(10)<<"\n\nEnter a number between 1 and 49.  "<<Remaining<<" numbers still need to be chosen.   ";
		
		if(!(std::cin>>Input))
		{
	
			std::cin.sync();

			std::cout<<"\nPlease enter a valid number.";
			
			std::cin.clear();

		}

		InputNumbers.push_back(Input);

	}
	
	std::cout<<"\n";

	for(InputCounter=InputNumbers.begin();InputCounter!=InputNumbers.end();InputCounter++)
	{

		std::cout<<*InputCounter<<"\n";

	}
	//int NumberInputs;
}



The behaviour is a little bizarre. I use this as test data: 1m3 33 m55 1s2 m2i3 2s6g The letters are there to test the robustness of the input handler. As you can see, the theory is that if the input is invalid (i.e. not an integer), there should be some kind of error handling going on. Thing is, the cin buffer is read one character at a time, so using my test data gives me this: As you can see, the buffer isn't clearing properly, and the results are listed at the bottom. I can't see a way round this behaviour. Hacking around with the test data sometimes leads to list elements holding the value -83029409 etc. I know I could use std::getline(), but all that did was put 0 into the list element if the input was invalid. This is really irritating, actually. If any of you have any ideas about how to hack around this, I'd love to hear them. Thanks for your help, ukdeveloper.
Advertisement
When you get invalid input, you can clear the input buffer - try stream.ignore(std::numeric_limits<int>::max(), '\n');.

That will clear the rest of the line, regardless of its length.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
You add Input to your list whether it is valid or not. You need that line to be in an else statement, that way invalid inputs don't result in odd values getting stored.

1m3
> 1 is stored to Input, 5 left, m3 still in cin
> m is invlid, cin is cleared, but 1 is still Input, so it has been added twice
33
> 33 is stored to Input, 3 left, cin empty
m55
> m is invlid, cin is cleared, but 33 is still Input, so it has been added twice
1s2
> 1 is stored to Input, 1 left, s2 still in cin
> s is invlid, cin is cleared, but 1 is still Input, so it has been added twice

Which brings us to the end.

CM

This topic is closed to new replies.

Advertisement