int/float validation

I am trying to write a program which asks the user to answer simple arithmetic problems. One of the issues I am having with writing it is that if the user enters in a decimal number, the program goes into an infinite loop. I want to be able to check to make sure the user entered an int, but my tests do not seem to work. An example test is below.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  #include <iostream>

int main()
{
    int a = 0;
    std::cout << "Enter an int: ";
    std::cin >> a;
    
    if(static_cast<int>(a) == a)
    {
        std::cout << "a is an int." << std::endl;
    }
    else
    {
        std::cout << "a is not an int." << std::endl;
    }
}
to make sure the user entered an int,

http://www.cplusplus.com/forum/beginner/206234/
Last edited on
Hello Meden,

Not seeing your original code I am perplexed as to why it would cause an infinite loop. I do not see the point of line 9. Doing the "static_cast<int> (a)" and then checking it against it's self is mostly pointless. On line 7 if you enter 2 or 2.5 it come out 2, at least on my system, because anything stored in an "int" will drop the decimal portion.

I think what you want to do with your if statement is compare types, but you have no other type to compare to.

If you enter anything other than a number you could check with:

1
2
3
4
5
6
7
8
9
while (!std::cin)  //  Check if cin has failed.
{  
	//  You end up her if something other than a number is entered like a letter.
	std::cout << "\n cin failed" << std::endl;
	std::cin.clear();  // <---Reset the failed bits of the stream.
	std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');  // <--- Clear the input buffer.
	std::cout << "Enter an int: ";
	std::cin >> a;
}


As I have tested your code I have found that 2, 2.5 and "a" all say that they are "int"s. Now if you make "a" a double then the if statement will work and any time you cast "a" as an "int" you will drop any decimal portion leaving you with a whole number.

Hope that helps,

Andy
Thanks for the replies. I had thought if I posted too much code, I wouldn't get anyone to respond. Here is my original code, though the operationFunction() is not yet fully implemented. I am able to check for anything other than a number just fine, but a decimal number does something to the buffer which does not allow the user to enter new input. The result is a nearly infinite loop. It is the difficultyLevelFunction() which fails to stop this from happening because I don't know how to do it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#include <iostream>
#include <ctime>
#include <cstdlib>
#include <vector>
#include <cmath>
#include <limits>

std::vector<int> question(int, int, int, int);
int difficultyLevelFunction();
int operationFunction();

int main()
{
	int questionAttempts = 0;
	int totalCorrectAnswers = 0;
	std::vector<int> mainRecordHolder;
	int difficultyLevel = 0;
	int operation = 0;

	while (true)
	{
		if (questionAttempts >= 10)
		{
			if (static_cast<double>(totalCorrectAnswers) / questionAttempts >= 0.75)
			{
				std::cout << std::endl;
				std::cout << "Congratulations, you are ready to go to the next level!";
			}
			else
			{
				std::cout << std::endl;
				std::cout << "Please ask your teacher for extra help.";
			}
			std::cout << std::endl << std::endl;
			questionAttempts = 0;
			totalCorrectAnswers = 0;
		}
		if (questionAttempts == 0)
		{
			operation = operationFunction();
			difficultyLevel = difficultyLevelFunction();
		}

		srand(static_cast<unsigned int>(time(0)));
		int response = rand() % 4;
		int previousCorrectAnswers = totalCorrectAnswers;

		int num1 = rand() % (static_cast<int>(pow(10, difficultyLevel)) - 1) + 1;
		int num2 = rand() % (static_cast<int>(pow(10, difficultyLevel)) - 1) + 1;

		mainRecordHolder = question(num1, num2, questionAttempts, totalCorrectAnswers);
		questionAttempts = mainRecordHolder[0];
		totalCorrectAnswers = mainRecordHolder[1];

		if (totalCorrectAnswers > previousCorrectAnswers)
		{
			switch (response)
			{
			case 0:
				std::cout << "Very good!";
				break;
			case 1:
				std::cout << "Excellent!";
				break;
			case 2:
				std::cout << "Nice work!";
				break;
			case 3:
				std::cout << "Keep up the good work!";
			}
			std::cout << std::endl << std::endl;
		}
	}
}

std::vector<int> question(int number1, int number2, int questionAttempts, int correctAnswers)
{
	int userAnswer = 0;
	int response = rand() % 4;
	std::vector<int> record;
	record.push_back(questionAttempts);
	record.push_back(correctAnswers);

	std::cout << "How much is " << number1 << " times " << number2 << "?" << std::endl;

	while (record[0] < 10)
	{
		std::cout << "Your answer: ";
		std::cin >> userAnswer;

		record[0] += 1;
		if (userAnswer == number1 * number2)
		{
			record[1] += 1;
			return record;
		}

		switch (response)
		{
		case 0:
			std::cout << "No.  Please try again.";
			break;
		case 1:
			std::cout << "Wrong.  Try once more.";
			break;
		case 2:
			std::cout << "Don't give up!";
			break;
		case 3:
			std::cout << "No.  Keep trying.";
		}
		std::cout << std::endl;
		srand(static_cast<unsigned int>(time(0)));
		response = rand() % 4;
	}
	return record;
}

int difficultyLevelFunction()
{
	int maxDifficulty;
	int difficultyLevel;

	if (std::numeric_limits<int>::max() < RAND_MAX)
	{
		maxDifficulty = log10(std::numeric_limits<int>::max()) - 1;
	}
	else
	{
		maxDifficulty = log10(RAND_MAX) - 1;
	}

	while(true)
	{
		std::cout << "Enter the level of difficulty: ";
		std::cin >> difficultyLevel;

		if (static_cast<int>(difficultyLevel) == difficultyLevel 
			&& difficultyLevel > 0 
			&& difficultyLevel <= maxDifficulty)
		{
			return difficultyLevel;
		}
		std::cout << "Invalid entry.  Difficulty level must be between 1 and "
			<< maxDifficulty << "." << std::endl;
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}
}

int operationFunction()
{
	int operation = 0;

	while (true)
	{
		std::cout << "Pick a type of arithmetic problem to study." << std::endl
			<< "Enter 1 for addition." << std::endl
			<< "Enter 2 for subtraction." << std::endl
			<< "Enter 3 for multiplication." << std::endl
			<< "Enter 4 for division." << std::endl
			<< "Enter 5 for a random mixture." << std::endl
			<< "Your selection: ";
		std::cin >> operation;

		if (operation >= 1 && operation <= 5)
		{
			return operation;
		}
		std::cout << "Invalid entry.  Difficulty level must be between 1 and 5."
			<< std::endl;
		std::cin.clear();
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	}
}
Last edited on
the usual way to force the issue is to read everything you get from the keyboard as a string, always. Convert that to a numeric type, handling it if the user put in something invalid (request another value and complain, usually). Your check is fine... but what you probably want is
string to double to int. If fabs(double-int) > eps, not equal, therefore not integer. Eps or epsilon or something with a name like that is in limits header.
Topic archived. No new replies allowed.