1
int main(void)
{
   int valid_input();
   int ll_input=0;
   int resp;
   hash_table obj;
   int bucket;  
   while(1)
   {
      ll_input=valid_input();
      if(ll_input>10)
      {
        break;
      }
      obj.insert(ll_input);

   }
   obj.print_ll();


   return 0;
}    

int valid_input()

{
  int input;
  printf("\n\rEnter the value: ");
  std::cin >> input;
  while(std::cin.fail())
  {
    std::cin.clear();
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
    printf("\n\rBad entry!\n\rEnter the value: ");
    std::cin>>input;
  }
  return input;
}

The above is the code, it works correctly for most alphanumeric combinations, it rejects user inputs like a,10aa,1003abc, etc. However, it on inputs like 100a, 100b, etc, passes. What could the reason be for this?

The following is the output in the snapshot enter image description here

Anurag
  • 651
  • 4
  • 18
  • 1
    `std::cout` and then `printf`? Please, remove this eye-catcher. – LogicStuff Feb 02 '16 at 22:24
  • edited! Any help on the problem? – Anurag Feb 02 '16 at 22:27
  • 3
    Failing on `10aa` and `1003abc` seems absurd. Are you sure? (Btw, I rather wanted to see `std::cout` :D ) – LogicStuff Feb 02 '16 at 22:28
  • The `failbit` is not set when reading `100q` as a decimal integer because the scanner reads digits until a non-digit is found. The letter `q` signals the end of the number. It is not an error. – Thomas Matthews Feb 02 '16 at 22:28
  • 3
    Any input starting with a number should work as `cin` will leave the rest of the input in the stream. See this: http://ideone.com/EFt3Eb – NathanOliver Feb 02 '16 at 22:29
  • 2
    `cin >> input` stops reading as soon as it finds any non number. "100a" is two tokens: "100" and "a". "100" passes, but "a" would not but was never read by this function because it was satisfied by "100". If you want to catch stuff like this, read strings, and then parse the strings into `int`s with `std::stoi`or `strtol`. – user4581301 Feb 02 '16 at 22:34
  • I now understand why for 10aaa it was accepting the number. But as you can see in the snapshot it passes 10, Then it again asks Enter the value(gdb shows it automatically read 33). I suppose 'cin' takes in 'aaa' and outputs 'Bad Entry'. But why 33? It is not the ascii for 'a' – Anurag Feb 02 '16 at 23:00
  • @user4581301 Also what would be the solution to check and reject the alphanumeric combination? – Anurag Feb 02 '16 at 23:02
  • This isn't the problem, but `\n` starts a new line. There's no need for those `\r`s. – Pete Becker Feb 02 '16 at 23:24
  • 1
    Why 33? Why not? The number is invalid and not to be used so who cares what the value is. No point wasting time setting it to anything, so `cin` most likely doesn't. Google "Undefined Behaviour" to read more. The Quick-and-dirty solution is in the answer below. If `std::stoi` won't compile, C++11 isn't enabled. If for some reason you can't enable it, let me know and I'll paste in the old way. – user4581301 Feb 02 '16 at 23:25

1 Answers1

1

cin >> input stops reading as soon as it finds any non number, so "100a" is interpreted as two tokens: "100" and "a".

"100" is converted into an int and exits the while(std::cin.fail()) loop. This leaves "a" sitting in the stream to bedevil the next read of cin.

The quick way to catch this, (quick in terms of writing and explaining, not the fastest to execute if the input is error-prone)

std::string token;
while (true) // or a countdown to kick out the truly moronic
{
    cin >> token;
    try
    {
        size_t pos;
        int result = std::stoi(token, &pos);
        if (pos == token.size())
        {
             return result;
        }
    }
    catch (...) // don't really care why std::stoi failed
    {
    }
}

std::stoi documentation.

Faster approaches, if errors are expected, use strtol or similar and skip the exception handling overhead.

user4581301
  • 33,082
  • 7
  • 33
  • 54