How to handle stoi conversion error?

I am trying to convert a string to an integer using stoi, I have never touched on try catch and don't know how to handle the exception or error given by stoi. The code below is what I've managed to produce but I can't seem to be able to let the user re-enter once the stoi conversion has failed. Shouldn't cin>>input be enough to start the try catch again? Really new to try catch and error handling. I am trying to loop the input for user when stoi conversion fails. Appreciate it if anyone can give me some examples.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

String input;
int amount_input;

cout<<"Enter the amount of cake"<<endl;
cin>>input;

try{
amount_input = stoi(input);	
		
}
catch(exception &err)
{
cout<<"Conversion failure"<<endl;
cin>>input;
}
Last edited on
It is a strong temptation to bug the user to fix errors, but as the years have passed I have come stronger and stronger of the opinion that it is the Wrong ThingTM to do.

If the user’s input is incorrect, complain (be specific) and quit.

Good job!


Here is a more complete example for you to boggle over.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <string>

int main()
{
  int number_of_slices_of_cake;
  try
  {
    std::cout << "How many slices of cake? ";
    std::string s;
    getline( std::cin, s );
    number_of_slices_of_cake = std::stoi( s );
    if (number_of_slices_of_cake < 0) throw 1;
  }
  catch (...)
  {
    std::cerr << "You must answer with a whole number >= 0.\n";
    return 1;
  }

  int number_of_cakes = (number_of_slices_of_cake + 7) / 8;
  std::cout << "Great! That's " << number_of_cakes << " cakes!\n";
}

Notice that on line 13 we also throw if the number of slices is invalid. It does not matter what we throw, since we are just trying to use the same response as a non-integer input. In other words, the catch (...) block catches both the 1 we throw and either of the things that stoi() throws.

If we wanted to have a different complaint then we would do something other than throwing that 1. (Such as complain and quit.)


Hope this helps.
I can't seem to be able to let the user re-enter once the stoi conversion has failed.
In addition to @Duthomhas you need a loop like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
String input;
int amount_input;

bool is_ok = false;

while(not is_ok)
{
cout<<"Enter the amount of cake"<<endl;
cin>>input;

try{
amount_input = stoi(input);	
is_ok = true; // Note: is_ok is only set to true when stoi(...) was successfull
}
catch(exception &err)
{
cout<<"Conversion failure: "<< err.what() <<endl; // Note: what() tells the exact error
cin>>input; // Edit: don't
}
Last edited on
The problem with

1
2
3
4
while (user has not input what I want)
{
  …
}

is that you now have an infinite loop.

Don’t do that.
@Dunthomhas , if so is there a better way to let the user re-enter the input if the conversion has failed?
Ways of dealing with the infinite loop
1
2
3
4
   while ( not is_ok )
   {
      ....
   }



- Give it what it wants; enter something that makes is_ok true

- CTRL-C

- taskkill /f /IM myprog.exe

- close command window

- power off

- take a hammer to the PC
mrtammy2008 wrote:
if so is there a better way to let the user re-enter the input if the conversion has failed?

No. Make the user try again properly.

For many program, that means starting the program over.

For a (much) larger program, where this input is a smaller piece of the program, exit back to the menu/whatever the user used to get to the part where input was desired.

Don’t forget to tell the user what went wrong.
is that you now have an infinite loop.
No, due to line 13.

Ways of dealing with the infinite loop
Actually it depends on the requirements. One way could be:
1
2
3
4
5
6
7
8
9
10
11
12
13
catch(exception &err)
{
cout<<"Conversion failure: "<< err.what() <<endl; // Note: what() tells the exact error
cin>>input;
}
if(not is_ok)
{
  cout << "Exit? y/n" << endl;
  char exit_ch;
  cin >> exit_ch;
  is_ok = (exit_ch == 'y');
}
}
No, due to line 13.

Yes, due to line 9.

Why are you wasting your time on this?



’Cause... whatever.
Topic archived. No new replies allowed.