How to check for a valid user input in C++ - c++

I'm trying to build the Bulls & Cows game in C++. I've implemented most of the logic. The game runs continuously with the use of an infinite loop and generates a random value at each run.
What I'm trying to do now is to now is to take the user input and run the code if the input is valid (can ONLY be a 4 digit integer). This is my implementation:
#include ...
using namespace std;
vector<int> getDigits(int modelValue) {
vector<int> vectorValue;
int extractedDigit = 0;
int modulant = 10000;
int divisor = 1000;
for (int i = 0; i < 4; i++) {
extractedDigit = (modelValue % modulant) / divisor;
vectorValue.push_back(extractedDigit);
modulant /= 10;
divisor /= 10;
}return vectorValue;
}
int main() {
for (;;) {
int model = rand() % 9000 + 1000;
int guess = 0000;
int bulls = 0;
int cows = 0;
int counter = 1;
cout << "This is the random 4-digit integer: " << model << endl;
cout << "Enter a value to guess: ";
cin >> guess;
if ((guess >= 1000) && (guess <= 9999) && (cin)) {
vector<int> modelVector = getDigits(model);
vector<int> guessVector = getDigits(guess);
for (int i = 0; i < 4; i++) {
if (find(modelVector.begin(), modelVector.end(), guessVector[i]) != modelVector.end()) {
if (modelVector[i] == guessVector[i]) { bulls += 1; }
else { cows += 1; }
}
}cout << "There are " << bulls << " bulls and " << cows << " cows" << endl;
}
else {
cout << "Please enter a valid 4-digit integer between 0000 and 9999" << endl;
cin.clear();
}
}return 0;
}
But when I run and input something invalid, what I get is a continuously running .

There's nothing wrong with the way you read the user input, it just doesn't check for the input type before assigning the value into your 'guess' variable.
So, if an user put any value that isn't accepted by the integer type it would crash your application generating this infinite loop.
To protect your integer variable from wrong user inputs you must replace your direct input assignment:
cin >> guess;
By a protected one:
while(!(cin >> guess) || (guess < 1000)){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Please, try again: ";
}
Into the while above you can see the "numeric_limits::max()" which is explained here:
Returns the maximum finite value representable by the numeric type T. Meaningful for all bounded types.
At the end you have a while holding the user into this reading loop while its input is under 1000 (as requested) or isn't a valid integer.

Try out cin.ignore(). It'll help you flush the cin buffer.

Related

While getting user input, I set the smallest and largest numbers input into their own variables, but for whatever reason they start out = to 0

While getting user input, I set the smallest and largest numbers input into their own variables, but for whatever reason they start out = to 0.
Code:
#include <iostream>
using namespace std;
int main()
{
int num;
string var;
int sum = 0;
int i;
int largest = INT_MIN;
int smallest = INT_MAX;
int j = 0;
int prime = 0;
do {
cout << "Please enter a series of numbers, press (Q or q) to process: ";
cin >> num;
if (cin.fail())
{
cin.clear();
cin >> var;
if (var != "Q" && var != "q")
{
cout << "Invalid input, try again" << endl;
}
}
if (num > largest)
{
largest = num;
}
if (num < smallest)
{
smallest = num;
}
if (num == 0 || num == 1)
{
prime = prime;
}
else
{
for (i = 2; i <= num / 2; i++)
{
if (num % i == 0)
{
j = 1;
break;
}
}
if (j == 0)
{
prime++;
}
}
sum += num;
cout << "The corresponding element for the cumulative total sequence is: " << sum << endl;
cin.ignore(sum, '\n');
} while (var != "Q" && var != "q");
cout << endl;
cout << "Largest number: " << largest << endl;
cout << "Smallest number: " << smallest << endl;
cout << "How many prime numbers? " << prime << endl;
cout << "Have a great day!" << endl;
}
Here is an example of the program being run.
Program example
The smallest number here should be 8, and the issue is that it begins at 0. The same thing with the largest number.
Program example #2
Your loop is testing the "num" variable even if the user inputs q or Q, adding an else statement else break; after the if (var != "Q" && var != "q") will fix it.
For the future, always keep in mind that when the "if" function fails, it will move on to the next line, if you need to to not execute, you either need to break out of the loop or change the structure of your code.

while loop turning into an infinite loop for non bool values [duplicate]

I'm trying to build the Bulls & Cows game in C++. I've implemented most of the logic. The game runs continuously with the use of an infinite loop and generates a random value at each run.
What I'm trying to do now is to now is to take the user input and run the code if the input is valid (can ONLY be a 4 digit integer). This is my implementation:
#include ...
using namespace std;
vector<int> getDigits(int modelValue) {
vector<int> vectorValue;
int extractedDigit = 0;
int modulant = 10000;
int divisor = 1000;
for (int i = 0; i < 4; i++) {
extractedDigit = (modelValue % modulant) / divisor;
vectorValue.push_back(extractedDigit);
modulant /= 10;
divisor /= 10;
}return vectorValue;
}
int main() {
for (;;) {
int model = rand() % 9000 + 1000;
int guess = 0000;
int bulls = 0;
int cows = 0;
int counter = 1;
cout << "This is the random 4-digit integer: " << model << endl;
cout << "Enter a value to guess: ";
cin >> guess;
if ((guess >= 1000) && (guess <= 9999) && (cin)) {
vector<int> modelVector = getDigits(model);
vector<int> guessVector = getDigits(guess);
for (int i = 0; i < 4; i++) {
if (find(modelVector.begin(), modelVector.end(), guessVector[i]) != modelVector.end()) {
if (modelVector[i] == guessVector[i]) { bulls += 1; }
else { cows += 1; }
}
}cout << "There are " << bulls << " bulls and " << cows << " cows" << endl;
}
else {
cout << "Please enter a valid 4-digit integer between 0000 and 9999" << endl;
cin.clear();
}
}return 0;
}
But when I run and input something invalid, what I get is a continuously running .
There's nothing wrong with the way you read the user input, it just doesn't check for the input type before assigning the value into your 'guess' variable.
So, if an user put any value that isn't accepted by the integer type it would crash your application generating this infinite loop.
To protect your integer variable from wrong user inputs you must replace your direct input assignment:
cin >> guess;
By a protected one:
while(!(cin >> guess) || (guess < 1000)){
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Invalid input. Please, try again: ";
}
Into the while above you can see the "numeric_limits::max()" which is explained here:
Returns the maximum finite value representable by the numeric type T. Meaningful for all bounded types.
At the end you have a while holding the user into this reading loop while its input is under 1000 (as requested) or isn't a valid integer.
Try out cin.ignore(). It'll help you flush the cin buffer.

C calculating sum correctly

I can get the sum every time the user inputs an integer until either a negative number or non-integer is inputted. Problem is my sum calculations are off. I.E user putting 1000; sum outputs 1111, then user inputs 2000, it adds up to 3333. Just any advice is appreciated. I'll still experiment around with my coding.
#include <iostream>
#include <cstdlib>
using namespace std;
int main()
{
int j , i = 0, k = 0,number;
double sum = 0;
cout << "Enter Positive integer number: ";
while(cin >> number)
{
cout << endl;
if( number < 0)//test if the number is negative
{
cout << "Ending program since user has input a negative number" <<endl;
break;
}
int temp = number;
int p = 1;
while( temp > 0) //counting number of digits
{
sum = sum+temp; //Sum attempt.
temp /= 10;
p *= 10;
i++;
}
cout << sum << endl;
j = i % 3;
p /= 10;
while( i > 0 )//display integer number with 1000 seperator
{
//this is giving me error
cout << char ((number/p) +'0');
number %= p;
p /= 10;
i--;
k++;
j--;
if ((k % 3 == 0 && i > 0)||(j == 0 && i > 2) )
{
cout <<",";
k = 0;
}
}
cout << endl << endl;
cout << "This program will exit if you input any non-integer characters\n";
cout << "Enter another integer number: ";
}
return 0;
}
It looks like you're trying to output an integer number with commas inserted at 1000 boundaries. ie: 1000000 would be displayed as 1,000,000.
This being the case, the easiest way to approach it might not be involving maths but simply to get a string representation of the int (atoi() for example) and count through that. From the back, count forward three chars, insert a comma, repeat until you run out of string.
The specifics of string handling are left as an exercise for the reader - looks like it's his homework after all. ;-)

Ensure unique input is entered and stored in an array

Is this program OK, or can it be improved (but simply)? How do I make sure no repeat numbers are entered?
int n;
int array[9];
cout<<"Enter Number Between 9-0 Only"<<endl;
for(int i = 0; i<=10; i++){
cout<<"Enter Number" <<(i+1)<<endl;
cin >> n;
if((n >= 0) && (n <=9)){
array[i]=n;
}
else{
cout<<"Numbers from 0-9 only\n"<<endl;
break;
}
}
(edit) complete, compiling code
To check if the numbers are used with higher performance, try something like this (using the working code from Jack Radcliffe):
#include <iostream>
using namespace std;
int main()
{
int n = 0;
int array[9] = {0};
bool isUsed[10] = {0};
for(int i = 0; i < 9; i++)
{
cout << "Enter Number " << (i + 1) << endl;
cin >> n;
if((n >= 0) && (n <= 9))
{
if (isUsed[n] == false)
{
array[i] = n;
isUsed[n] = true;
}
else
{
cout << "Number has already been used." << endl;
i--;
}
}
else
{
cout << "Numbers from 0-9 only." << endl;
i--;
}
}
return 0;
}
Optimization isn't exactly necessary with this simple of code, but it's this seems to be an exercise of practice, so why not practice optimized code, too?
Most of it is fine, though there are two problems standing out.
First, you have an array of size 9, but you are taking in 11 numbers since you're starting the for loop at 0 and going through to 10.
Second, since you have it so if the entered number is not between 0 and 9, inclusive, the for loop breaks. This entails that fewer than 9 numbers will be put into the array if an invalid number is entered. Change the entire loop to read this and you should be good:
for(int i = 0; i < 9; i++) {
cout << "Enter Number " << (i + 1) << endl;
cin >> n;
if((n >= 0) && (n <= 9))
array[i] = n;
else {
cout << "Numbers from 0-9 only\n" << endl;
i--;
}
}
The whole fire part was right, but I removed the break in the else-statement and added in the i--. I added that in so when the user is prompted to re-enter the number, the entry number will be at the correct index.
I hope this was helpful.

if else statement confused c++

#include <iostream>
using namespace std;
int main()
{
int positiveInteger;
cout << "Please input an integer up to 100." << endl;
cin >> positiveInteger;
int result = 0;
for (int i = 0; i <= positiveInteger; i++)
{
if ( positiveInteger >= 0 )
{
result += i;
}
else
{
cout << "Please input a positive integer." << endl;
}
}
cout << result;
return 0;
}
Above I have a for loop with an if else statement in the center. I am confused because I want it to be so when I enter a integer that is not negative it will loop the if result. But I want it to be so if I put in a negative number it says please input a positive integer. That's why I set it so in the if statement only numbers above and = to 0 would return the result, but if I enter a negative number I just get 0 I want it to say "Please input a positive integer". I don't understand what I'm doing wrong. Isn't the if statement if true pulls the if and if its not true pulls the else? Or am I missing something?
If you enter a negative number, you never get to enter the loop. An approach that fits better to such cases is:
do
{
input a number;
if( positive )
do something;
} while( not positive );
If I got it right, you want to
1. input a number;
2.1 If the number is positive you loop through it.
2.2 If it's negative you show the error message.
The problem is your loop, where the conditional is, checks if i (which is zero) is smaller then the number. However if you input a negative number i will be bigger then positiveInteger and you won't loop through the if. I fixed your code
using namespace std;
int main()
{
int positiveInteger;
cout << "Please input an integer up to 100." << endl;
cin >> positiveInteger;
int result = 0;
if ( positiveInteger >= 0 ){
for (int i = 0; i <= positiveInteger; i++)
{
result += i;
}
cout << result;
}
else {
cout << "Please input a positive integer." << endl;
}
return 0;
}
I think your code would benefit from some rearrangement. I'd structure it something like this:
do {
cout << "please enter a number between 1 and 100";
number = get_number():
} while (number < 1 || number > 100);
cout << sum_series(1, number);
The output you are getting is because your loop fails at non-negative numbers. You should try the following:
int main()
{
int positiveInteger;
cout << "Please input an integer upto 100." << endl;
cin >> positiveInteger;
int result = 0;
if ( positiveInteger < 0 )
{
cout << "Please input a positive integer." << endl;
}
else{
for (int i = 0; i <= positiveInteger; i++)
{
result += i;
}
cout << result;
}
return 0;
}
From my understanding, if the number is negative, you wish to take another input. But the cin statement is not under loop control to do it so. It just executes only one time irrespective of the nature of the number.