1

I have a menu creation system with a loop to check input. When the input is something like "2.4" or "2 4" it accepts "2" as the first input, then I guess "4" gets stored in the buffer and automatically passes as the next input without waiting.

These two solutions are the closest I could find, but I can't figure out how to implement the first (don't even understand most of what they're using) and the second still accepts non-int numbers.

Accept only integer to input

How to make cin take only numbers

relevant code (sorry, still trying to figure out formatting):

int menu(std::vector <std::string> options) //menu creation
{
int input;             //user selection
bool check = false;    //check for valid input
.
.
.
  while(!check)
  {
    std::cin >> input;

    if(std::cin.fail() || input <= 0 || input > static_cast<int>(options.size()))
    {
      std::cin.clear();
      std::cin.ignore();
      std::cout << wrongInput << std::endl;
    }
    else
    {
      check = true;       //change flag for valid input
    }
  }
return input;
}

I'd like the loop to outright reject anything non-int. I tried having a loop that would check each character sequentially so it would accept multi-digit ints, then fail on a space, "." or character, but it very was clumsy and still didn't work properly.

ZJN
  • 13
  • 4
  • 1
    read line per line and then use function like strtol to check the conversion occured AND that the whole content was read. – OznOg Apr 28 '19 at 19:06

1 Answers1

0

You can read one line, put it into a stringstream and then use std::nows to make sure whitespace is not allowed. To make sure that there are no remaining characters after the integer, just check EOF.

#include <iostream>
#include <sstream>
#include <string>

int main() {
  std::string line;
  std::stringstream temp;
  std::getline(std::cin, line);
  temp << line;
  int value;
  temp >> std::noskipws >> value;
  if(!temp.fail() && temp.eof()) {
    std::cout << "Parsed a 'pure' int: " << value << std::endl;
  } else {
    std::cerr << "Expected <int>" << std::endl;
  }
}

It will allow 123, 598324 but not <space>123 or 123.4

Filip Dimitrovski
  • 1,576
  • 11
  • 15
  • This works! However, now my loop gets stuck when rejecting invalid input- it claims every entry following is also invalid. I think this still counts as progress- thank you. – ZJN May 09 '19 at 02:35
  • @ZJN I haven't seen your loop, but it should work: https://repl.it/repls/WarlikeBestLinks – Filip Dimitrovski May 09 '19 at 07:48