Having trouble adding exception handling code to function that contains a do while loop

I need to add exception handling code to a function for entries that are not integers.  I am having trouble because the file contains a do while loop.

Here is the function:
int instructions( void )
{
   int choice;
   // ask user to enter a choice
   cout << "\nEnter a choice:\n" <<
                  "1  List all records.\n" <<
                  "2  Change record.\n" <<
                  "3  Add a record.\n" <<
                  "4  Delete a record.\n" <<
                  "5  Quit.\n";
   // ask user for choice until a valid choice is entered
      do {
            cout << "? ";
            cin >> choice;
           } while ( choice < 1 || choice > 5 );
    return choice; // return user choice
} // end function instructions

I tried this- but got caught in an infinite output loop-
int instructions( void )
{
   int choice;
   // ask user to enter a choice
   cout << "\nEnter a choice:\n" <<
                  "1  List all records.\n" <<
                  "2  Change record.\n" <<
                  "3  Add a record.\n" <<
                  "4  Delete a record.\n" <<
                  "5  Quit.\n";
   // ask user for choice until a valid choice is entered
try   {
         if (!(isdigit(choice))) throw exception();
         else
           do {
          cout << "? ";
          cin >> choice;
      } while ( choice < 1 || choice > 5 );
   }
   catch (...)  {
         cerr << "\nException error: Invalid Entry!\n";
   }    return choice; // return user choice
} // end function instructions
coririzzoAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

jkrCommented:
We already did that in http:Q_21223482.html - the idea was to

#include <stdlib.h>
#include <string>
#include <iostream>
using namespace std;

bool read_integer ( istream& is, int& i) {

   int n;
   string str;
   char* pcCnvEnd = NULL;

   getline(is,str); // read input

   n = (int) strtol(str.c_str(),&pcCnvEnd,10); // try to convert the string to int

   if ( *pcCnvEnd) // conversion did not end at the term. NULL -> invalid input
     return false;

   i = n; // conversion successful, was an int

   return true;
}

int instructions( void )
{
 int choice;

 // ask user to enter a choice
 cout << "\nEnter a choice:\n" <<
             "1  List all records.\n" <<
             "2  Change record.\n" <<
             "3  Add a record.\n" <<
             "4  Delete a record.\n" <<
             "5  Quit.\n";

 // ask user for choice until a valid choice is entered
 do {

   if ( !read_int(cin,choice)) continue; // go on in the loop if input was invalid

  } while ( choice < 1 || choice > 5 );

 return choice; // return user choice

} // end function instructions
0
udo_borkowskiCommented:
I would suggest that you rewrite your routine like this, since Exceptions should only be used of "exceptional situation" (and a wrong user input is not exceptional). Also you should not use exceptions for "control flow" purposes.

here my suggestion:

int instructions( void )
{
    char choice;
      do {

       // ask user to enter a choice
       cout << "\nEnter a choice:\n" <<
               "1  List all records.\n" <<
               "2  Change record.\n" <<
               "3  Add a record.\n" <<
               "4  Delete a record.\n" <<
               "5  Quit.\n";

       cout << "? ";
       cin >> choice;
       if (!(isdigit(choice))) {
            cerr << "\nException error: Invalid Entry!\n";
       }
   } while ( choice < '1' || choice > '5' );
   return (choice -'1')+1;
}


(BTW: the choice value in your code was not initialized)
0
coririzzoAuthor Commented:
Thanks jkr- your previous answer was great, but I wanted to try it with exception handling code.
udo_borkowski - I tried your solution, and am still getting an infinite output loop.  I think it may be due to this code from main:  

 while ( ( choice = instructions( ) ) != 5 ) {
            switch (choice){
            case 1:      listEMailObjs(file );
                  break;
            case 2:      updateRecord(file );
                  break;
            case 3:      insertRecord(file );
                  break;
            case 4:      deleteRecord(file);
                  break;
            default:      cout<< "Error";
                  break;
         }
      file.clear();    // reset eof indicator
   } // end while

One more dumb question- I am rather new here, and I don't know how to make my response show up as an "author comment".  
0
Cloud Class® Course: Amazon Web Services - Basic

Are you thinking about creating an Amazon Web Services account for your business? Not sure where to start? In this course you’ll get an overview of the history of AWS and take a tour of their user interface.

jkrCommented:
>>but I wanted to try it with exception handling code

OK, if it is about practising that I agree. You could e.g. try

#include <stdlib.h>
#include <string>
#include <iostream>
using namespace std;

enum InputError {

   NotAnInteger,
   SomethingUnknown
};

void read_integer ( istream& is, int& i) {

  int n;
  string str;
  char* pcCnvEnd = NULL;

  getline(is,str); // read input

  n = (int) strtol(str.c_str(),&pcCnvEnd,10); // try to convert the string to int

  if ( *pcCnvEnd) // conversion did not end at the term. NULL -> invalid input
    throw NotAnInteger;

  i = n; // conversion successful, was an int
}

int instructions( void )
{
int choice;

// ask user to enter a choice
cout << "\nEnter a choice:\n" <<
            "1  List all records.\n" <<
            "2  Change record.\n" <<
            "3  Add a record.\n" <<
            "4  Delete a record.\n" <<
            "5  Quit.\n";

// ask user for choice until a valid choice is entered
do {

  try {

    read_int(cin,choice);

  }
  catch ( InputError e) {

     if ( NotAnInteger == e) cout << "NotAnInteger\n";
       else cout << "Something unknown went wrong\n";

     continue;
  }

 } while ( choice < 1 || choice > 5 );

return choice; // return user choice

} // end function instructions
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
udo_borkowskiCommented:
> One more dumb question- I am rather new here, and I don't know how to make my response show up as an "author comment".  

Your comments appear as "author comment" to us (you will probably just see "Your comment")

0
udo_borkowskiCommented:
> udo_borkowski - I tried your solution, and am still getting an infinite output loop.  I think it may be due to this code from main:  ...

And this infinite output loop does not occur with jkr's solution?

And what exactly is written to the output?

Do I need to know what file you are "clearing" at the end of your case block?
0
coririzzoAuthor Commented:
Thanks jkr- that works!  I was wrong about the switch causing the problem.
Udo- you were right- I do see it as "your comment"- DUH
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.