Hi i'm attempting to validate a user input looking for an input of either 1 or 0. The string validating part seems to work fine but any integer based input has the console window accepting the input but not jumping over the if statement, returning the input (maxItems). Here is the code :
int RollingStats::GetOption()
{
int maxItems;
std::cout << "Please enter either to store data individually (0) or as a range(1)" << std::endl;
std::cin >> maxItems;
if ((!(std::cin >> maxItems) && maxItems != 0) | (!(std::cin >> maxItems) && maxItems != 1))
{
std::cin.clear();
std::cin.ignore(100, '\n');
std::cout << "Please enter an input of either 0 or 1" << std::endl;
GetOption();
}
return maxItems;
}
Any help would be appreciated.
Some issues in the code:
Using cin thrice (once before if and twice in the if condition) would require the user to input thrice
Using logical OR (||) instead of bit-wise or (|) in your if condition check.
Not checking if the input is an integer
You can do something like this instead:
int RollingStats::GetOption()
{
int maxItems;
std::cout << "Please enter either to store data individually (0) or as a range(1)" << std::endl;
std::cin >> maxItems;
if(!std::cin.good() || maxItems != 0 && maxItems != 1)
{
std::cin.clear();
std::cin.ignore(100, '\n');
std::cout << "Please enter an input of either 0 or 1" << std::endl;
maxItems = GetOption();
}
return maxItems;
}
Related
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
}
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 code that checks if index is an integer between 1 and the size of a vector member called options_ (menu implementation):
int ConsoleMenu::GetSelection() {
int index;
std::cout << "Please enter your selection index. " << std::endl;
while (!(std::cin >> index) || std::cin.get() != '\n' || index < 1 || index > options_.size()) {
std::cout << "Error. index must be a valid integer. Try again: " << std::endl;
std::cin.clear();
std::cin.ignore(256, '\n');
}
}
but sometimes when I input a number and press enter it seems as if the program does not recognize I pressed enter. Can someone please help?
Thanks a lot!
Read a line with getline(), parse it using a std::stringstream, and test if it meets your criteria:
int ConsoleMenu::GetSelection() {
std::cout << "Please enter your selection index. " << std::endl;
while (true) {
std::string line;
std::getline(std::cin, line);
std::stringstream linest(line);
int index;
if ((linest >> index) && index >= 1 && index < options_.size()) {
return index;
}
std::cout << "Error. index must be a valid integer. Try again: " << std::endl;
}
}
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
}