C++: How to solve a char bug in a do while loop? - c++

Can you help me to solve this bug?
It is a game where you need to guess the hidden number. The problem is that when I enter a character that isn't an integer number, the program outputs a message infinitely,
Here is bug message if i enter a char
but I would like to make this program to output only message "You haven't entered a number, please try again".
Here is a normal execution
#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <conio.h>
using namespace std;
main(){
int a,b;
char c;
START:
system("cls");
srand (time(NULL));
a = rand() % 100 + 1;
cout << "Guess The hidden Number Between 1 and 100" << endl;
do {
cout << endl<<" Enter Any Number : "; cin>>b;
if(b>100||b<1) cout<<" Try another number that is between 1 and 100!!!";
else {
if (b>a)
cout <<" =>Too Big";
else if (b<a)
cout <<" =>Too Small";
else if (b==a) {
cout<<" =>You've Guess It!!!"<<endl;
break;
}
}
}
while (b != a);
cout << endl << "Press 'q' to start. Press else to close ";
c = getch();
if (c=='q'||c=='Q') goto START;
}

Your code int b; cin >> b; will try to read integer and will fail if where is no integer in the stream. Fail bit of cin will be set, you can check it either with if(cin.fail()) {} or just if(cin) {}. So, you need to extract junk input from cin before the next read. You can reach this effect by actually reading anything from cin and then trying to convert it to an integer.
#include <iostream>
#include <string>
using namespace std;
int main() {
int b;
string s;
do {
cout << endl << "Enter Any Number: ";
getline(cin, s);
try {
b = stoi(s);
cout << "Your code goes here." << endl;
}
catch (invalid_argument& ex) {}
catch (out_of_range& ex) {}
} while (true);
}

Something like this
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
int main() {
int b;
char s[1];
do {
cout << endl << "Enter Any Number: ";
gets(s);
try {
b = atoi(s);
cout << "Your code goes here." << endl;
}
catch (invalid_argument& ex) {}
catch (out_of_range& ex) {}
} while (true);
}

What you are seeing is the stream breaking. When you do std::cin << intNum; with a non-integer input, the data types are non-compatible, so it doesn't know what to do. To "fix" the stream, you need to clear the stream of it's error state using std::cin.clear() then the standard practice is to ignore the rest of the line to avoid other invalid input. A code snippet would look something like this:
while(std::cin.fail())
{
std::cin.clear();
std::cin.ignore(1000000, '\n');
}
This will check if the stream is broken, clear the flag so it can take input again, then clear out the next 1000000 characters or to the next \n, whichever comes first.

Related

How can i check a variable type in a conditional statement in c++?

I am pretty new to c++ and im having an issue trying to get my program out of a loop when a string is entered for the variables cont, and answer. In python it is pretty easy to do simple checks but I am not sure what I should be doing in cpp. I tried doing a check using if(typeid(answer)) == typeid(string)) but this doesnt work. I havent tried putting a check for
'y'||'Y'||'n'||'N' for cont but im assuming it would be something like that? just check for those 4 characters?
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <string>
using namespace std;
int main() {
unsigned seed;
char cont = 'y';
int answer = 0;
seed = time(nullptr);
srand(seed);
rand() % 100 + 1;
cout << "Lets play a math game!\n";
while(cont == 'y')
{
int num1 = rand() % 100 + 1;
int num2 = rand() % 100 + 1;
cout << "What is the result of this addition? \n " << num1 << '\n' << "+" << num2 << endl;
cin >> answer;
if (typeid(answer)==typeid(string))
{
while(typeid(answer) == typeid(string))
{
cout << "Please enter an integer!" << endl;
cin >> answer;
}
}
else if (typeid(answer) == typeid(int)) {
if (answer == (num1 + num2)) {
cout << "You are correct, would you like to play again?" << endl;
cin >> cont;
} else {
cout << "You were incorrect, would you like to try again? enter y/n" << endl;
cin >> cont;
}
} else {
answer = 0;
cout << "You did not enter an integer!\n" << endl;
cout << "Would you like to try again?" << endl;
}
}
return 0;
}
How can i check a variable type in a conditional statement in c++?
You do that already, though I'd do this instead:
#include <type_traits>
#include <iostream>
int main() {
int answer =0;
if constexpr(std::is_same_v<int,decltype(answer)>) {
std::cout << "answer is indeed an int";
}
}
However, this will always print the expected answer is indeed an int, because answer is an int not something else. If the user enters invalid input the variable answer declared as int will not turn into a std::string.
would something like if(inRange(0,200,answer)) work?
No it would not. std::cin >> answer; either succeds to read a number, or it fails and then 0 is assigned to answer. You cannot decide if valid input was entered by looking at answer only.
To check if the user entered valid input you can check the state of the stream:
#include <iostream>
#include <limits>
int main() {
int answer =0;
while(!(std::cin >> answer)){
std::cout << "please enter a number\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
std::cout << answer;
}
Note that this accepts for example 42asdf as valid input, because std::cin >> answer does read 42 before it encounters something that is not a number. For something more sophisticated you can read a std::string and parse that.

C++ Exception handling Inside loop not working [duplicate]

I am just trying to write a simple program that reads from cin, then validates that the input is an integer. If it does, I will break out of my while loop. If not, I will ask the user for input again.
My program compiles and runs just fine, which is great. But it doesn't prompt for new input if I enter a non numeric value. What gives?
#include <iostream>
using namespace std;
int main() {
bool flag = true;
int input;
while(flag){
try{
cout << "Please enter an integral value \n";
cin >> input;
if (!( input % 1 ) || input == 0){ break; }
}
catch (exception& e)
{ cout << "Please enter an integral value";
flag = true;}
}
cout << input;
return 0;
}
C++ iostreams don't use exceptions unless you tell them to, with cin.exceptions( /* conditions for exception */ ).
But your code flow is more natural without the exception. Just do if (!(cin >> input)), etc.
Also remember to clear the failure bit before trying again.
The whole thing can be:
int main()
{
int input;
do {
cout << "Please enter an integral value \n";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
} while(!(cin >> input));
cout << input;
return 0;
}
Don't use using namespace std; Instead import what you need.
It's better to do input a line at a time. This makes behavior much more intuitive if you have multiple words on one line, or if you press enter before typing anything.
#include <iostream>
#include <sstream>
#include <string>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::flush;
using std::getline;
using std::istringstream;
using std::string;
int main() {
int input;
while (true)
{
cout << "Please enter an integral value: " << flush;
string line;
if (!getline(cin, line)) {
cerr << "input failed" << endl;
return 1;
}
istringstream line_stream(line);
char extra;
if (line_stream >> input && !(line_stream >> extra))
break;
}
cout << input << endl;
return 0;
}

Trying to make a loop to check the string for numbers only and negative numbers allowed in C++ im new to programming this is a class project

I'm trying to make a loop to check input strings for numbers only, and negative numbers are allowed. I'm new to programming, this is for a class project.
This code works, to an extent. When it shows the output, it does not show the first number, and does not allow - to be used. I cannot figure out where I'm going wrong in this.
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cctype>
using namespace std;
string userInput;
int i = 0;
bool checkInput(int);
int main()
{
do
{
cout << "Please enter a numeric value : ";
string userInput;
cin >> userInput[i];
}
while (!checkInput(userInput[i]));
system("pause");
return 0;
}
bool checkInput(int input)
{
string userInput;
int i;
cin >> userInput;
for (int i = 0; i < userInput.length(); i++)
if (isdigit(userInput[i]))
{
cout << "\nYour input " << userInput << " is a valid numeric input." << endl;
return true;
}
else
{
cout << "Please enter a valid numeric value: ";
cin >> userInput[i];
return false;
}
}
Your code doesn't work because you are not utilizing std::string correctly.
When main() prompts the user, it reads into a char of an empty std::string, which is undefined behavior. You should be reading into the std::string itself without calling its operator[] at all. operator>> has an overload for reading std::string values.
checkInput() is just all kinds of wrong. It takes an int as input instead of a std::string, but ignores that input and waits for the user to type in another string value. Then it loops through that string instead of the one read by main(), and only checks the 1st char before exiting. If the char is a digit, checkInput() returns true, and main() exits. Otherwise, checkInput() prompts the user to type in yet another char and then returns false, which then causes main() to prompt the user to type in yet another char. checkInput() does not actually loop through an entire string at all, and does no have any handling for the - character.
Try this instead:
#include "stdafx.h"
#include <iostream>
#include <string>
#include <cctype>
#include <limits>
using namespace std;
bool checkInput(const string &);
int main()
{
string userInput;
cout << "Please enter a numeric value : ";
do
{
cin >> userInput;
if (checkInput(userInput))
break;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Please enter a valid numeric value: ";
}
while (true);
cout << "\nYour input " << userInput << " is a valid numeric input." << endl;
system("pause");
return 0;
}
bool checkInput(const string &input)
{
if (input.empty())
return false;
string::size_type i = 0;
if (input[0] == '-')
{
++i;
if (i == input.length())
return false;
}
do
{
if (!isdigit(input[i]))
return false;
}
while (++i < input.length());
return true;
}
However, the best way to handle this situation is to simply not allow the user to enter non-integer values to begin with. operator>> has overloads for reading integer values, both signed and unsigned types. In this case, reading int values will suffice. Let cin do all of the input validation for you:
#include "stdafx.h"
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int userInput;
cout << "Please enter a numeric value : ";
while (!(cin >> userInput))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Please enter a valid numeric value: ";
}
cout << "\nYour input " << userInput << " is a valid numeric input." << endl;
system("pause");
return 0;
}

How to forbid the inclusion of non-numbers?

I have this program:
#include <iostream>
#include <string>
using namespace std;
int main()
{
int i=0;
float reader, tot = 0;
while(i!=10)
{
cout << "Insert a number: " << endl;
cin >> reader;
if(cin)
{
tot += reader;
i++;
}
else
{
cout << "Error. Please retry." << endl;
cin.clear();
}
}
cout << "Media: " << tot/i << endl;
return 0;
}
In the IF() i want the user to insert ONLY FLOAT VALUES in "reader" variable.
I want that if the user inserts a number, the program continues... else the program should re-ask to the user to insert a correct value.
How to do this checking the INPUT? I tried with a TRY CATCH but it didn't work.
Thanks in advance!
"How to do this checking the INPUT?"
It's already ensured by
cin >> reader;
that only valid float values can be entered by the user. The way to check for validity is
if( cin >> reader ) {
tot += reader;
i++;
}
else {
cout << "Error. Please retry." << endl;
cin.clear();
std::string dummy;
cin >> dummy; // <<< Read invalid stuff up to next delimiter
}
Here's the fully working sample.
"I tried with a TRY CATCH but it didn't work."
To get exceptions from std::istream operations, set the std::istream::exceptions mask.
Just check the result of operator>>:
if (cin >> reader) {
// user gave you a float
tot += reader;
i++;
}
else {
cout << "Error. Please retry." << endl;
// clear the error flag on cin, and skip
// to the next newline.
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
Your original program was fine except you need to skip over that bad input when you get an error. Simply clearing the error is not enough:
#include <iostream>
#include <string>
#include <limits> // include this!!!
using namespace std;
int main()
{
int i=0;
float reader, tot = 0.0f; // tot needs to be float
while(i!=10)
{
cout << "Insert a number: " << endl;
if( cin >> reader )
{
tot += reader;
i++;
}
else
{
cout << "Error. Please retry." << endl;
cin.clear();
// Then you ned to skip past the bad input so you
// don't keep tripping the same error
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
}
}
cout << "Media: " << tot/i << endl;
return 0;
}
The function cin.ignore() ignores as many input characters as possibly up until the end-of-line character '\n'. The std::numeric_limits<std::streamsize>::max() function tells us the maximum number possible characters that can be stored in an input buffer.
If it is confusing an alternate way to skip the bad input would be to simply read up to the next line into a std::string.
else
{
cout << "Error. Please retry." << endl;
cin.clear();
// Then you need to skip past the bad input so you
// don't keep tripping the same error
std::string skip;
std::getline(cin, skip); // read the bad input into a string
}

std::cin doesn't throw an exception on bad input

I am just trying to write a simple program that reads from cin, then validates that the input is an integer. If it does, I will break out of my while loop. If not, I will ask the user for input again.
My program compiles and runs just fine, which is great. But it doesn't prompt for new input if I enter a non numeric value. What gives?
#include <iostream>
using namespace std;
int main() {
bool flag = true;
int input;
while(flag){
try{
cout << "Please enter an integral value \n";
cin >> input;
if (!( input % 1 ) || input == 0){ break; }
}
catch (exception& e)
{ cout << "Please enter an integral value";
flag = true;}
}
cout << input;
return 0;
}
C++ iostreams don't use exceptions unless you tell them to, with cin.exceptions( /* conditions for exception */ ).
But your code flow is more natural without the exception. Just do if (!(cin >> input)), etc.
Also remember to clear the failure bit before trying again.
The whole thing can be:
int main()
{
int input;
do {
cout << "Please enter an integral value \n";
cin.clear();
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
} while(!(cin >> input));
cout << input;
return 0;
}
Don't use using namespace std; Instead import what you need.
It's better to do input a line at a time. This makes behavior much more intuitive if you have multiple words on one line, or if you press enter before typing anything.
#include <iostream>
#include <sstream>
#include <string>
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::flush;
using std::getline;
using std::istringstream;
using std::string;
int main() {
int input;
while (true)
{
cout << "Please enter an integral value: " << flush;
string line;
if (!getline(cin, line)) {
cerr << "input failed" << endl;
return 1;
}
istringstream line_stream(line);
char extra;
if (line_stream >> input && !(line_stream >> extra))
break;
}
cout << input << endl;
return 0;
}