-1

I'm trying to write in C++ a function (leggiInteroEstrIncl) that prompts the user to type by keyboard an integer number included in a given range (between minimo and massimo).

Following is the function I wrote and then a statement, in the main(), to invoke it:

#include <iostream>

using namespace std;

int leggiInteroEstrIncl(string stringaDaStampare, int minimo, int massimo) {

  int numInserito = 0;
  bool errore = false;

  do {
    errore = false;
    cout << stringaDaStampare << " (un numero intero compreso tra " << minimo
         << " e " << massimo << " estremi inclusi): ";

    try {
      cin >> numInserito;
    } catch (...) {
      errore = true;
      cout << "Hai inserito un numero non valido, prova ancora" << endl;
    }

    if (errore == false && (numInserito < minimo || numInserito > massimo)) {
      errore = true;
      cout << "Hai inserito un numero al di fuori dell'intervallo richiesto: "
           << minimo << " <-> " << massimo << endl;
    }

  } while (errore);

  return numInserito;
}

int main() {
  int number = 0;

  number = leggiInteroEstrIncl(
      "Inserire la cifra in Yen da ripartire in banconote e monete", 1, 30000);

  system("pause");
  return 0;
}

If I type a valid integer number which is not included in the specified range, this piece of software works and asks the user to type again, but if I type something which is not a number, for example the word "hello", this software goes in a sort of loop and doesn't stop to ask the user to type again.

Could you please tell me what is wrong with it?

Thank you

t.niese
  • 39,256
  • 9
  • 74
  • 101
Gabriele
  • 41
  • 2
  • 1
    Possible duplicate of [c++ moving to next element in a file.txt](https://stackoverflow.com/questions/24498894/c-moving-to-next-element-in-a-file-txt) – t.niese Jun 11 '18 at 05:38
  • 1
    You need to check if the `cin >> numInserito` was successful or if the `failbit` was set, using `fail()`. If it failed, you need `.clear()` so that the input stream would ignore it and continue with the next input. – t.niese Jun 11 '18 at 05:41
  • If you post code here, you should translate your code to english wording. Most of the time an expert can understand the problem even if the names of the variable and functions are unknown. But the question and answer should also help other people if they have a similar problem. – t.niese Jun 11 '18 at 05:45

2 Answers2

1

You can use std::string to get input:

string insertio;
cin >> inserito;

and then use one of this function:

http://en.cppreference.com/w/cpp/string/basic_string/stol

which throws proper exception if there isn't a number in string.

If you need to check more solutions, check this one:

How to determine if a string is a number with C++?

BartekPL
  • 2,290
  • 1
  • 17
  • 34
  • Thank you very much, I will take your advice and try to read a string and then convert it into an integer using the stoi function. I have one last question: I don't understand why the stoi function lets me type something like "34 word" and recognize this as the integer 34. Instead, I would like only numbers to be accepted. Do I have to control the string by myself character by character or can it still be done using the stoi function? Thank you – Gabriele Jun 11 '18 at 22:28
  • @Gabriele Actually, I don't have better idea, but I'm pretty sure that there are some. In this case you can use some idea from this question's answers https://stackoverflow.com/questions/53849/how-do-i-tokenize-a-string-in-c. Once more idea is using `stringstream` to extract from it single token, but you can find that usage in another stackoverflow questions. – BartekPL Jun 12 '18 at 12:11
1

This

cin >> numInserito;

attempts to read in a number and nothing else.
It will succeed with a number, as you have observed.
With a non-number it will fail, but not in a way to trigger the catch part.
It will instead just not read anything in and especially it will leave the non-number in the input stream.
If you then continue trying to read in a number, it will continue failing.
When reading in a number fails you need to read in whatever there is and probably ignore it.
In order to ignore the non-number, read it in as a string and do nothing with it
(as described in the answer by BartekPL):

string insertio;
cin >> inserito;
Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • Wouldn't it be possible to keep trying to read an integer but then clear the input buffer if a proper integer is not typed? I tryed with fflush(stdin) inside the catch but it didn't solve the problem. – Gabriele Jun 11 '18 at 14:01
  • Trying to read integers and then, in case of failure, clearing the input by reading a string is exactly what I mean and describe above. Flushing the input is not portable and should not be used. – Yunnosch Jun 11 '18 at 16:53