strange behaviour while pressing enter when recieving input with conditions with cin - c++

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;
}
}

Related

Accept only integer to 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";
}

Validating binary input in C++

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;
}

Cheking of cin result c++

I need to request a size of array, which should be posite number. Look at the function of input and cheking of it.
indexType get_array_size(){
//indexType - size_t; MAX = max of unsigned int
long long ansver;
while(true){
std:: cout << "Enter size of array{0..." << MAX/2-1 << "} ";
bool ans = std:: cin >> ansver;
if(ansver < 0 || !(ans)){
std:: cout << "Incorect size!" << std::endl;
ansver = 0;
continue;
}
break;
}
return ansver;
}
How it must work: if ansver < 0 or input incorrect(some chars for example) new request, else return obtained value. But in practice only the first request is sent, and then only cout-s "Incorect size" if input was incorrect. Please help. Ps sorry for not good english=)
When an input stream gets in a bad state, you have to:
Clear the state.
Discard the current input.
before entering new data.
while(true){
std:: cin >> ansver;
if (cin.fail()) {
std::cout << "Bad input!" << std::endl;
cin.clear(); // unset failbit
cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
continue;
}
if(ansver < 0 ) {
std::cout << "Incorect size!" << std::endl;
continue;
}
break;
}

How can you make input take strings and int? c++

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
}

C++ user entry and error handling

I am currently writing a knights tour program and I am trying to think of the best way to handle the problem I am running into. My goal is to prompt the user to enter in several inputs for a starting place on the board. This means that the user needs to be able to type in several numbers which in my opinion, this means I need an empty array that can accept the input. I am coding in C++ and this is what I have so far:
#include <iostream>
#include <iomanip>
using namespace std;
int greeting(){
cout << "Welcome to the Knights Tour! Please, enter your desired starting places." <<
endl << "Enter any numbers 1-64, and type -1 to start." << endl << endl;
int board[8][8] = {{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}
};
for (int row = 0; row < 8; row++){
for(int column=0; column<8; column++){
cout << setw(3) << board[row][column] << " ";
}
cout << endl;
}
cout << endl;
}
int main(){
greeting();
}
I have tried several methods to accept the user input but what I am ultimately trying to do is allow only integer input from 1-64 and allow the user to type -1 to exit the loop.
Thanks for the help!
int position = 0;
std::string line;
do
{
while (std::cout << "Select position 1-64, or type -1 to exit\n" &&
std::getline(std::cin, line))
{
std::istringstream iss(line);
position = 0;
if (iss >> position &&
(position == -1 ||
position 1 <= position && position <= 64))
{
char c;
if (!(iss >> c))
break;
std::cerr << "trailing character also found on input line, please try again\n";
}
else
std::cerr << "you entered an invalid position, please try again\n";
}
if (1 <= position && position <= 64)
{
// do/call your position-related work here...
}
} while (position != -1 && std::cin);