Rejecting decimals

Hi, I am currently writing a program that should only accept integers values and reject any value that isn't an integer and ask for another input, however I have not been able to get my program to this. Any help or advice on how to solve this problem would be greatly appreciated.

I have included my whole code below as I'm not sure where in the code I should change this. Please ignore any of the random looking things such as the fill characters, I have been asked to include these

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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
#include <iostream> //preprocessor directive needed in order to use std::cout
                    //and std::cin
#include <iomanip> //preprocessor directive in order to use any manipulator that
                   //uses an argument
#include <cmath> //preprocessor directive in order to use square root, etc
                 //functions
#include <ctime> //defines ctime() for random numbers

#include <cstdlib> //defines rand(), srand(), RAND_MAX

#include <windows.h>//needed for text and  background colour changes

#define Pi 2.0*acos(0.0) //Defining Pi as a more accurate value

#include <limits>

#include <string>
using namespace std; //avoids having to uses std:: with cout and cin

int main (int argc, char* argv[])
{
	HANDLE hConsole;
    hConsole = GetStdHandle (STD_OUTPUT_HANDLE);
    
	system("COLOR F0"); //inverts colours
	
	//Declaring the variables
	int a, b, MinNum, MaxNum; //Integer values a and b
 	double x, y; //Decimal values x and y
 	string ans= "Y";
    
 	
 	
 	//Student number and date
 	SetConsoleTextAttribute(hConsole, 117);
	 cout << "STUDENT ID: 15910237"
 	<< "\nDATE: 16/03/2018"
 	<< endl;
 	
 	//Tells the user what is happening 
	SetConsoleTextAttribute(hConsole, 240);
	cout << "\n\nThis program computes a value of Pi using the Monte Carlo"
	<< " method and compares this value to the actual value of Pi."
	<< "\nIt does this for a range of user inputted integer values"
	<< " in steps of 100.\n\nThe values a and b represent"
	<< " the minimum and maximum number of randomly generated"
	<< " points (x, y)\nrespectively;"
	<< " where 0 < (x,y) < 1. If 2 values are entered for a and b such that"
	<< " they are greater than 80 and less\nthan 850,"
	<< " the program will automatically"
	<< " select the minimum and maximum values to be 80 and 850 respectively"
	<< "\n\nThe Monte Carlo Pi is calculated by finding the number of"
	<< " points that fall with in a circle of radius 1 \nin the positve"
	<< " quadrant of a graph and dividing this value by the total number"
	<< " of points before multiplying by 4"
	<< endl;
	
	do
    {
	  //Ask user for input
	  cout << "\n\nPlease enter an integer value for a," 
	  " where (a > 0): ";
	  
	  while(!(cin >> a))
	  {
        cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        SetConsoleTextAttribute(hConsole, 252);
        cout << "\nValue for a is not valid, please enter an integer value"
        << " greater than 0: ";
        SetConsoleTextAttribute(hConsole,240);
      }
	  
	  if (a < 0)
	  {
 		SetConsoleTextAttribute(hConsole, 252);
		cin.clear();
		cin.ignore(numeric_limits<streamsize>::max(), '\n');
		cout << "\nValue for a is not valid, please enter an integer"
		<< " value greater than 0: ";
		cin >> a; //enter value b if original value is invalid
		SetConsoleTextAttribute(hConsole,240);
	  }
	 
	  cout << "\n\nPlease enter an integer value for b," 
	  " where (b > 0): ";
	  
	  while(!(cin >> b))
	  {
	    cin.clear();
        cin.ignore(numeric_limits<streamsize>::max(), '\n');
        SetConsoleTextAttribute(hConsole, 252);
        cout << "\nValue for b is not valid, please enter an integer value"
        << " greater than 0: ";
        SetConsoleTextAttribute(hConsole,240);
 	  }
	  
	  if (b < 0)
	  {
 		SetConsoleTextAttribute(hConsole, 252);
		cout << "\nValue for b is not valid, please enter an integer value"
		<< " gretaer than 0: ";
		cin >> b; //enter value b if original value is invalid
		SetConsoleTextAttribute(hConsole,240);
	  }
	  
	  if (a < 80 && a < b && a >0)
	  {
        MinNum = a;
	  }

	  else if (b < 80 && b < a && b > 0)
	  {
	  	MinNum = b;
	  }
	  
	  else
	  {
	  	MinNum = 80;
	  }
	  
	  if (b > 850 && b > a && b > 0)
	  {
	  	MaxNum = b;
	  }
	  
	  else if (a > 850 && a > b && a >0)
	  {
  		MaxNum = a;
	  }
	  
	  else
	  {
	  	MaxNum = 850;
	  }
	  
	  
	  
	
	  srand( time( 0 ) ); //Creates the seed time
	
	  //Print out headings
	  SetConsoleTextAttribute(hConsole, 143);
	  cout << "\n\n" << left  
	  << setfill('d')
	  << setw( 20 ) << "Total Points "
 	  << setw( 3 ) << " $ "
	  << setw( 20 ) << "Points in Circle "
	  << setw( 3 ) << " $ "
	  << setw( 20 ) << "Value Monte Carlo Pi"
	  << setw( 3 )  << " $ "
	  << setw( 20 ) << "Difference vs Pi "
	  << endl;
	
 
 	
   	  for ( int N = MinNum; N <= MaxNum; N += 100 ) //perform loop 
		  		  			  	 		   	  	  	//with increment 100
   	  {
   	     int NumberOfPointsInCircle = 0; //Number of times a point is in the
      	  						   	  //circle of radius 1
      
         for ( int i = 0; i < N; i++ ) //Loop to generate random points
      	 {
          	 x = ((double) rand() / (RAND_MAX)); //Random x coordinate
         	 y = ((double) rand() / (RAND_MAX)); //Random y coordinate
         
		 	 if ( sqrt((x * x) + (y * y)) < 1 ) //Distance formula
		 	 {
		  	  	NumberOfPointsInCircle++; //if equation is correct, add 1 to 
			 						//number of points in circle
             }		
         
      	 }
      	 double MonteCarloPi = 4.0 * NumberOfPointsInCircle / N; //Formula to 
      	 //calculate Pi using Monte Carlo method
      
      	 double DifferencePi = MonteCarloPi - Pi; //formula to calculate the 
      	 //difference between Monte Carlo Pi and actual Pi
      
      	 //Print out the results
	  	 SetConsoleTextAttribute(hConsole, 245);
	  	 cout << setfill ('d') 
	  	 << scientific << setprecision ( 4 ) << left
	  	 << setw(20) << N;
	  	 SetConsoleTextAttribute(hConsole, 143);
	  	 cout << setw( 3 ) << " $ " ;
	  	 SetConsoleTextAttribute(hConsole, 245);
	  	 cout << setw( 20 ) << NumberOfPointsInCircle;
	  	 SetConsoleTextAttribute(hConsole, 143);
	  	 cout << setw( 3 ) << " $ ";
	  	 SetConsoleTextAttribute(hConsole, 245);
	  	 cout << setw( 20 ) << MonteCarloPi;
	  	 SetConsoleTextAttribute(hConsole, 143);
	  	 cout << setw( 3 ) << " $ ";
	  	 SetConsoleTextAttribute(hConsole, 245);
	  	 cout << setw( 20 ) << DifferencePi
	  	 << endl;
      }
   	  
	  SetConsoleTextAttribute(hConsole, 240);	 
	  cout << "\nWould you like to try again? (Y/N): ";
  	  cin >> ans;
   
   	  if (ans == "N" || ans == "n")
   	  {
	   	 cin.get();//end program
      }
   	
   	  while (ans != "Y" && ans != "N" && ans != "y" && ans != "n")
   	  {
  	      SetConsoleTextAttribute(hConsole, 252);
   		  cout << "\nInvalid input, please enter Y or N: ";
   		  SetConsoleTextAttribute(hConsole, 240);
   		  cin >> ans;
   		  
	  }
    }
   	while (ans == "Y" || ans == "y");
   
   	//Let user see results before ending program 
	SetConsoleTextAttribute(hConsole,240);
	cout << "\n\nPress <Enter> to end the program";
	cin.get();
}
Last edited on
Hello jordanhood1234,

As I look over the program I see int a, b, MinNum, MaxNum; //Integer values a and b . First you should always initialize your variables it is just good practice. As it is these variables contain whatever value, garbage, that is tat that memory address when the variable was created. Defined as an "int" any floating point number you try to store in these will only store the whole number and drop the decimal part.

Second thing I noticed is the double x, y; //Decimal values x and y . What is the point? You use these variables to store the return value of "rand()", but "rand" returns an "int", whole number, which you type cast into a double. In the end this double is a whole number with .0 unless the number can not be stored correctly and the decimal part is used, not likely though.

using namespace std; //avoids having to uses std:: with cout and cin
. Not to be mean here, but the truth is it means you and who ever told you to use this is lazy. Using this line WILL get you in trouble some day. Now is the time to learn what is in the "std::" name space.

It would help if you said which variables you do not want the floating point numbers in and where you think the problem is.

Hope that helps,

Andy
Hi Handy Andy,

Thank you very much for your response. Can you just clarify that by initialising a variable you mean set it equal to 0?

Thanks for pointing out my double x, y; //Decimal values x and y . I will fix that now

As for using namespace std;, that is just what we were taught, I have only been coding for a couple of weeks. Could you explain briefly why using this will cause problems?

Sorry I should have made this part more clear, I want the 2 inputs, a and b, to be rejected if they are not integer values. I have managed to find a way to reject a character input using
1
2
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');

However like I say I have not found a way to reject decimal inputs. I thought maybe using the modulo function might work or using if (a == '.'); but I can't seem to implement them.

Something is telling me these methods won't work but not completely sure why. I am also not sure why this problem arises as I just assumed if I declared a and b to be integers, the program would automatically reject any input that wasn't an integer
Last edited on
closed account (E0p9LyTq)
As for using namespace std;, that is just what we were taught, I have only been coding for a couple of weeks. Could you explain briefly why using this will cause problems?

https://www.geeksforgeeks.org/using-namespace-std-considered-bad-practice/
Thanks FurryGuy, I will give this a read.
closed account (E0p9LyTq)
A quick, dirty and ugly way to determine if a double or int was entered (using static_cast<>):

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

int main()
{
   double entry;

   std::cout << "Enter an integer value: ";
   std::cin >> entry;

   // cast to int and then double and compare
   if (static_cast<double>(static_cast<int>(entry)) != entry)
   {
      std::cout << "\nYou entered a double.\n";
   }
   else
   {
      std::cout << "\nYou entered an integer.\n";
   }
}

Possible output:
Enter an integer value: 12.75

You entered a double.


Enter an integer value: 12

You entered an integer.

As long as there is no decimal digits other than zero entered in any significant position the number is considered an int.

You could also simply cast your input to int, ignoring any fractional part, and proceed on.
Last edited on
Hello jordanhood1234,

Can you just clarify that by initialising a variable you mean set it equal to 0?
Yes. You can either say variable = 0 or what I use these days, if your compiler is set to the C++11 standard or after, an empty set of {}s. This will set an "int" to zero, a double to 0.0 and a char to '\0'. "std::strings" are empty when defined, so there is no need to set them. Any other numeric type of a variable will be set to the type of zero that is needed.

Just because you were taught to use using namespace std; does not mean it is right. I would say that your teacher does not want to have to read all those "std::" in all the programs. As I once heard "No such thing as bad student, only bad teacher". I use to think as you do that this makes it easy and less typing until I used a variable name or function name that is in the standard name space and spent hours trying to change my function only to find the compiler was trying to use "std::sort()" instead of my function "sort()". An example of what can happen. After about a week of typing "std::cout", "std::cin" and "std::endl;" I just started doing it without thinking. Now I have learned more of what is in the standard name space and I find that my VS IDE is a big help with this.

As I said inputting a floating point number into an "int" variable will keep the whole number and drop the decimal part without changing the whole number. Not a problem. If you put a break point in the IDE to stop the program after you input "a" or just use a "cout" statement you would find that an entry of "10.23456" would just be "10" when you check the value of "a".

Lines 64 - 72 is the right approach to handle a non numeric value. As long as you enter a number, whole or floating point, this will bypass the while loop. Otherwise you will stay in the while loop until you enter a valid number.

I took a quick look at FurryGuy's link and it may explain this better than what I did. Be sure to give it a read.

Hope that helps,

Andy
Hello jordanhood1234,

I hate it when I think of something after I post a message.

You are using the line std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');. One of the things I found early on when I joined the forum is if you include "windows.h" in your program this need to be followed with #undef max; before the header file "limits" is included because "limits" will use a different definition of "max()'.

Line 140. Each time through the do/while loop you are giving "srand()" a new seed. Maybe. "srand" only needs to be called once and should be near the beginning of the program. I usually put this after the area where I define my variables. Since the parameter sent to "srand" is an "unsigned int" I write the line as srand(static_cast<std::size_t>(time(0)));. Where "size_t" is another name for "unsigned int".

Hope that helps,

Andy
Hi FurryGuy and Andy, thank you so much for taking the time to help me, I really appreciate it. I have taken all advice on board and can hopefully clean up my codes in the future
closed account (E0p9LyTq)
@jordanhood1234, if you really want to clean up your C++ code, use the <random> and <chrono> libraries instead of the C libraries.

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
include <iostream>
#include <chrono>
#include <random>

int main()
{
   enum COIN { Heads = 1, Tails };

   // create a randum number engine
   std::default_random_engine URNG;

   // seed the engine with the current system time
   URNG.seed(static_cast<unsigned> (std::chrono::system_clock::now().time_since_epoch().count()));

   // create an int distribution that gives either a heads or tails result
   std::uniform_int_distribution<> dis(Heads, Tails);

   // let's flip that coin 20 times!
   for (int flip = 1; flip <= 20; flip++)
   {
      COIN tossed = static_cast<COIN> (dis(URNG));

      if (tossed == Heads)
      {
         std::cout << "Heads ";
      }
      else
      {
         std::cout << "Tails ";
      }
      if (flip % 8 == 0)
      {
         std::cout << '\n';
      }
   }
   std::cout << '\n';
}
Hi another thing to learn very soon is the use of functions. You may have only been learning for 2 weeks, but I think that if one is ready to write 200+ Lines Of Code (LOC), then one should be ready to learn functions too.

http://www.cplusplus.com/doc/tutorial/functions/

So candidates for what could go into a function:

* The body of any loop, if statement
* a series of if else else statements
* code already identified with the comment like lines 181 to 198 for example

It a bad idea to have so much code in a do loop lines 58 to 218, it's harder to comprehend. If one uses a do loop, always put the while part on the same line as the closing brace, so it's not confused with a regular while loop.

Some other things:

Try to avoid #define statements, make it a const variable in main instead:
const double Pi = acos(-1.0);

It's good practise to declare your variable 1 per LOC. Also make sure to initialise them with something. Ideally wait until you have a sensible value to use, then declare and initialise all in one statement.

You can make the logic simpler in respect the answers Y or N, make use of the toupper() or tolower() function , so you only have to compare Y and N , not Y , y, N , n

http://www.cplusplus.com/reference/locale/toupper/

Good Luck !!
Topic archived. No new replies allowed.