I have the following bit of code that I'm using to check whether an input is a multiple of 3, 5 or Both. If the user does not enter a number I would like it to print the value stored in UserInput. At the moment it is just returning 0, any suggestions would be much appreciated!
#include <iostream>
using namespace std;
int main()
{
int UserInput;
cout << "Please enter a number:";
cin >> UserInput;
if (!cin) {
cout << UserInput;
}
else if ((UserInput%3 == 0) && (UserInput%5 == 0)) {
cout << "FizzBuzz";
}
else if (UserInput%3 == 0) {
cout << "Fizz";
}
else if (UserInput%5 == 0) {
cout << "Buzz";
}
}
If the user input cannot be read into an int, cin is placed in a fail state and nothing is read. The contents of UserInput are useless to you. You will have to take cin out of the error state with clear and read the stream into something guaranteed to be able to hold the user's input like a std::string.
if (std::cin >> UserInput) // Get input and make sure input was read check for good input
{
// do the fizbuzz thing.
}
else
{
std::cin.clear(); // remove the error flags set by reading a non-number
std::string badinput;
getline(std::cin, badinput); // read the bad input.
std::cout << "User input: " << badinput << std::endl; // write the bad input
}
Related
I found this similar question being asked so many times but I still couldn't find a solution for mine.
In my case, I want to display something when the user enters a number from 1 - 5, give an error when he inputs something wrong like characters, "3g", "3.", "b3" and any float number.
I tried the code below, but it created so many other problems. Like if I enter 3g or 3.5, it'll only take the 3 and ignore the rest so the (!cin) doesn't work at all.
Second, if I input something like a character, the __userChoice will be automatically converted into 0 and the program prints out "Please select a number from 1 to 5." instead of "Invalid input, please input an integer number.\n", which is what I want.
cout << "Please select: ";
cin >> __userChoice;
if (__userChoice > 0 && __userChoice < 5) {
cout << "You select menu item " << __userChoice <<". Processing... Done!\n";
}
else if (__userChoice == 5) {
Finalization(); //call exit
}
else if (__userChoice <= 0 || __userChoice > 5) {
cout << "Please select a number from 1 to 5.\n";
}
else (!cin) {
cout << "Invalid input, please input an integer number.\n";
}
cin.clear();
cin.ignore(10000, '\n');
operator>> is not guaranteed to output a meaningful integer value if a failure occurs, but you are not checking for failure before evaluating __userChoice, and the way your ifs are structured the else (!cin) check will never be reached. But even if operator>> is successful, you are not checking if the user entered more than just an integer.
To do what you are asking for, you should read from std::cin into a std::string first using std::getline(), and then use std::istringstream or std:stoi() (or equivilent) to convert the string to an int with error checking.
For example:
bool strToInt(const std::string &s, int &value)
{
std::istringstream iss(s);
return (iss >> value) && iss.eof();
// Or:
std::size_t pos;
try {
value = std::stoi(input, &pos);
}
catch (const std::exception &) {
return false;
}
return (pos == input.size());
}
...
std::string input;
int userChoice;
std::cout << "Please select: ";
std::getline(std::cin, input);
if (strToInt(input, userChoice))
{
if (userChoice > 0 && userChoice < 5)
{
std::cout << "You selected menu item " << userChoice <<". Processing... Done!\n";
}
else if (userChoice == 5)
{
Finalization(); //call exit
}
else
{
std::cout << "Please select a number from 1 to 5.\n";
}
}
else
{
std::cout << "Invalid input, please input an integer number.\n";
}
I have this snippets of code from my original long program, and as much as it looks simple, it doesn't work correctly! I am brand-new to c++ language, but I know in Java that would be the way to do it (Regardless of the syntax).
Simply put, this should ask the user for an input to answer the following multiplication (5*5), however, it should also check if the user entered a wrong input (not number), keep asking the user again and again... Somehow, it keeps running forever without taking a new input!!
I hope to get, not only an answer, but also a reason for such an error!
int main() {
int userAnswer;
bool isValidAnswer = true;
cout << 5 << " * " << 5 << " = ";
cin >> userAnswer;
cin.ignore();
do {
if (cin.fail()) { //user input is not an integer
cout << "Your answer is not valid! Please enter only a natural number: ";
cin >> userAnswer;
cin.ignore();
} else {
isValidAnswer = false;
}
} while (isValidAnswer);
return 0;
}
Well you need to clear the error state before accepting new input. Call cin.clear() then cin.ignore() before trying to read input again.
I would do something like.
cout << "Enter a number: ";
cin >> number;
while(cin.fail())
{
cin.clear();
cin.ignore(1000, '\n'); //some large number of character will stop at new line
cout << "Bad Number Try Again: ";
cin >> number;
}
First, cin.fail() is not going to adequately check if your answer is a natural number or not with the type set to int (could also be negative).
Second, your boolean isValidAnswer is really checking if it's is an invalid answer.
Third (and most importantly), as another answer suggests, you should put in cin.clear() to clear the failure state, and then followed by cin.ignore(), which will remove the failed string from cin.
Fourth, cin will only check if an int exists somewhere in the string. You'll need to perform your own string comparison to determine if the entire input is a int (see answer below, based on this answer).
Updated:
#include <iostream>
#include <string>
#include <cstdlib>
using namespace std;
bool isNum(string line)
{
char* p;
strtol(line.c_str(), &p, 10);
return *p == 0;
}
int main() {
int userAnswer;
string input;
bool isInvalidAnswer = true;
cout << 5 << " * " << 5 << " = ";
while (isInvalidAnswer) {
if (!(cin >> input) || !isNum(input)) {
cout << "Answer is not a number! Please try again:\n";
cin.clear();
cin.ignore();
}
else {
userAnswer = atoi(input.c_str());
if (userAnswer < 0) { //user input is not an integer
cout << "Answer is not a natural number! Please try again:\n";
} else {
isInvalidAnswer = false;
}
}
}
cout << "Question answered!\n";
return 0;
}
I am trying to make a cin where the user can only enter 0 to 1. If the user doesnt enter those numbers then he should get an error saying "Please enter within the range of 0 to 1."
But its not working.
What am i doing wrong?
int alphaval = -1;
do
{
std::cout << "Enter Alpha between [0, 1]: ";
while (!(std::cin >> alphaval)) // while the input is invalid
{
std::cin.clear(); // clear the fail bit
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // ignore the invalid entry
std::cout << "Invalid Entry! Please Enter a valid value: ";
}
}
while (0 > alphaval || 1 < alphaval);
Alpha = alphaval;
Try this:
int alphaval;
cout << "Enter a number between 0 and 1: ";
cin >> alphaval;
while (alphaval < 0 || alphaval > 1)
{
cout << "Invalid entry! Please enter a valid value: ";
cin >> alphaval;
}
If you want to trap empty lines I'd use std::getline and then parse the string to see if the input is valid.
Something like this:
#include <iostream>
#include <sstream>
#include <string>
int main()
{
int alphaval = -1;
for(;;)
{
std::cout << "Enter Alpha between [0, 1]: ";
std::string line;
std::getline(std::cin, line);
if(!line.empty())
{
std::stringstream s(line);
//If an int was parsed, the stream is now empty, and it fits the range break out of the loop.
if(s >> alphaval && s.eof() && (alphaval >= 0 && alphaval <= 1))
{
break;
}
}
std::cout << "Invalid Entry!\n";
}
std::cout << "Alpha = " << alphaval << "\n";
return 0;
}
If you want a different prompt on error then I'd put the initial prompt outside the loop and change the inner prompt to what you prefer.
Week one of C++, starting with Peggy Fisher's Learning C++ on Lynda.com.
This is what I came up with. Love to receive feedback.
int GetIntFromRange(int lower, int upper){
//variable that we'll assign input to
int input;
//clear any previous inputs so that we don't take anything from previous lines
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
//First error catch. If it's not an integer, don't even let it get to bounds control
while(!(cin>>input)) {
cout << "Wrong Input Type. Please try again.\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
//Bounds control
while(input < lower || input > upper) {
cout << "Out of Range. Re-enter option: ";
cin.ignore(numeric_limits<streamsize>::max(), '\n');
//Second error catch. If out of range integer was entered, and then a non-integer this second one shall catch it
while(!(cin>>input)) {
cout << "Wrong Input Type. Please try again.\n";
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
}
}
//return the cin input
return input;
}
As the exercise was to order Hamburgers, this is how I ask for the amount:
int main(){
amount=GetIntFromRange(0,20);
}
is it possible, say your trying to do calculations so the primary variable type may be int... but as a part of the program you decide to do a while loop and throw an if statement for existing purposes.
you have one cin >> and that is to take in a number to run calculations, but you also need an input incase they want to exit:
Here's some code to work with
#include <iostream>
using namespace std;
int func1(int x)
{
int sum = 0;
sum = x * x * x;
return sum;
}
int main()
{
bool repeat = true;
cout << "Enter a value to cube: " << endl;
cout << "Type leave to quit" << endl;
while (repeat)
{
int input = 0;
cin >> input;
cout << input << " cubed is: " << func1(input) << endl;
if (input = "leave" || input = "Leave")
{
repeat = false;
}
}
}
I'm aware they wont take leave cause input is set to int, but is it possible to use a conversion or something...
another thing is there a better way to break the loop or is that the most common way?
One way to do this is read a string from cin. Check its value. If it satisfies the exit condition, exit. If not, extract the integer from the string and proceed to procss the integer.
while (repeat)
{
string input;
cin >> input;
if (input == "leave" || input == "Leave")
{
repeat = false;
}
else
{
int intInput = atoi(input.c_str());
cout << input << " cubed is: " << func1(intInput) << endl;
}
}
You can read the input as a string from the input stream. Check if it is 'leave' and quit.. and If it is not try to convert it to a number and call func1.. look at atoi or boost::lexical_cast<>
also it is input == "leave" == is the equal operator. = is an assignment operator.
int main() {
cout << "Enter a value to cube: " << endl;
cout << "Type leave to quit" << endl;
while (true)
{
string input;
cin >> input;
if (input == "leave" || input == "Leave")
{
break;
}
cout << input << " cubed is: " << func1(atoi(input.c_str())) << endl;
}
}
you can use like
int input;
string s;
cint>>s; //read string from user
stringstream ss(s);
ss>>input; //try to convert to an int
if(ss==0) //not an integer
{
if(s == "leave") {//user don't want to enter further input
//exit
}
else
{
//invalid data some string other than leave and not an integer
}
}
else
{
cout<<"Input:"<<input<<endl;
//input holds an int data
}
I'm basically expecting a number as input. The magnitude is negligible now as I know my else if loop works fine. But testing if its a number proves to be a bit trickier. I just want to call the function again and start over if the user enters in something alphanumeric or just plain words. Or pressed enter. Something that is not a number. I tried !cin since I am inputting into int numTemp, but that just results in an infinite loop that spills out "what is the bitrate" countless times. Anyone know what I'm doing wrong? I tried putting cin.clear() and cin.ignore(100, "\n") inside the first if statement but to no avail. Thanks in advance.
bool iTunes::setBitRate()
{
cout << "What is the bitrate? ";
int numTemp;
cin >> numTemp;
if (!cin)
{
cout << "WRONG" << endl;
setBitRate();
}
else if( numTemp < MIN_BITRATE || numTemp > MAX_BITRATE)
{
cout << "Bit Rate out of range" << endl;
setBitRate();
}
else
{
bitRate = numTemp;
}
}
You can just read a string from the user instead of an int, and then check it and prompt for new input if you don't like the string (e.g. if it doesn't cleanly convert to a number, which you can check with strtol).
If you want to check whether the input is a number or character, you can use isdigit, but you have to pass it a char and then when it is a digit you can convert it to a int with atoi.
When the statement cin >> numTemp fails due to non-numeric input the character causing the failure is NOT removed from the input stream. So the next time the stream extraction operator is called it will see the same non-numeric input as the last time. To avoid this you need to skip the existing input.
One way of doing this is to use getline() to read a complete line of text before trying to converting it to and integer. The folllowing code snippet illustrates this:
#include <cstdlib>
bool getint(istream& in, int & out) {
string line;
getline(in, line);
char* endptr;
out = strtol(line.c_str(), &endptr, 10);
return endptr!=line.c_str();
}
bool iTunes::setBitRate()
{
cout << "What is the bitrate? ";
int numTemp;
if ( !getint(cin, numTemp) && cin )
{
cout << "WRONG" << endl;
setBitRate();
}
else if( numTemp < MIN_BITRATE || numTemp > MAX_BITRATE)
{
cout << "Bit Rate out of range" << endl;
setBitRate();
}
else
{
bitRate = numTemp;
}
}
NOTE: You should also check the status of cin after each read to ensure that some error has not occurred.
i think this will helps
bool iTunes::setBitRate()
{
cout << "What is the bitrate? ";
int numTemp = 0;
cin >> numTemp;
if (!numTemp)
{
cout << "WRONG" << endl;
setBitRate();
}
else if( numTemp < MIN_BITRATE || numTemp > MAX_BITRATE)
{
cout << "Bit Rate out of range" << endl;
setBitRate();
}
else
{
bitRate = numTemp;
}
}