954,505 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Only accept an alphabetical character

I've just completed an exercise from a book wherein the task is to display a menu of choices each associated to an alphabetical character. The program is to reject invalid characters and only finishing when a valid choice is made. Below is my solution, it achieves the task but I'd like to know if there is a completely easier approach.

// chap05q03.cpp  
// C++ Primer Plus, Fifth Edition
// Chapter 6, Page 276.
// Programming Exercise # 3
// 4 Dec, 2007.

#include <iostream>

int main()
{
   using namespace std;
   char ch;
   char msg[] = "\nPlease enter  c, p, t or g: ";
   bool invalid = true;
		
   cout << "Please enter on of the following choices:\n\n";
   cout << "c) carnivore        p) pianist\n";
   cout << "t) tree             g) game\n";
	
   while (invalid)
   {
      cin >> ch;
      if ((ch != 'c') && (ch != 'p') && (ch != 't') && (ch != 'g'))
      {
         cin.clear();
	 while (cin.get() != '\n')
	    continue;
	 cout << msg;
      }
      else 
         invalid = false;	// we've got a correct entry, exit loop.
   }
   switch (ch)
   {
	case 'c'	: cout << "Option 'c' selected"; break;
	case 'p'	: cout << "Option 'p' selectd"; break;
	case 't'	: cout << "Option 't' selected"; break;
	case 'g'	: cout << "Option 'g' selected"; break;
	default 	: cout << "It will never get her"; break;
   }
   system("PAUSE");
   return 0;
}


Any advice welcome.

superjacent
Junior Poster in Training
66 posts since Nov 2007
Reputation Points: 11
Solved Threads: 3
 

You could put the switch inside the loop (better as a do...while), let the default case handle the erroneous inputs. What is your if( ) condition becomes the while( ) condition.

Val

vmanes
Posting Virtuoso
1,914 posts since Aug 2007
Reputation Points: 1,268
Solved Threads: 228
 

You could put the switch inside the loop (better as a do...while), let the default case handle the erroneous inputs. What is your if( ) condition becomes the while( ) condition.

Val


Thanks for the advice, very much appreciated. I've altered the code as suggested and is a lot 'cleaner' looking. Below is the result.

// chap05q03-a.cpp  
// C++ Primer Plus, Fifth Edition
// Chapter 6, Page 276.
// Programming Exercise # 3
// 4 Dec, 2007.

// modified after advice from DaniWeb C++ forum.

#include <iostream>

int main()
{
using namespace std;
char ch;
char msg[] = "\nPlease enter  c, p, t or g: ";
bool invalid = false;
		
cout << "Please enter on of the following choices:\n\n";
cout << "c) carnivore        p) pianist\n";
cout << "t) tree             g) game\n";
	
do 
{
	cin >> ch;
	invalid = false;  
	switch (ch)
	{
		case 'c': cout << "Option 'c' selected\n"; break;
		case 'p': cout << "Option 'p' selectd\n"; break;
		case 't': cout << "Option 't' selected\n"; break;
		case 'g': cout << "Option 'g' selected\n"; break;
		default : cout << msg;
			cin.clear();
			while (cin.get() != '\n')
				continue;
			invalid = true;
	}
} while (invalid);
system("PAUSE");
return 0;
}
superjacent
Junior Poster in Training
66 posts since Nov 2007
Reputation Points: 11
Solved Threads: 3
 

You can also let 'c','p' & 't' fall through to 'g'

switch (ch)
	{
		case 'c': 
		case 'p': 
		case 't': 
		case 'g': cout << "Option '" << ch << "' selected\n";
                             break;

		default : cout << msg;
			cin.clear();
			while (cin.get() != '\n')
				continue;
			invalid = true;
	}
Tight_Coder_Ex
Posting Whiz in Training
215 posts since Feb 2005
Reputation Points: 47
Solved Threads: 17
 
You can also let 'c','p' & 't' fall through to 'g'

Thanks, very much appreciated.

superjacent
Junior Poster in Training
66 posts since Nov 2007
Reputation Points: 11
Solved Threads: 3
 
Thanks for the advice, very much appreciated. I've altered the code as suggested and is a lot 'cleaner' looking.


Not bad, although it's still not formatted properly .
By the way, what does cin.clear(); do? You might want to look it up.
Another thing to look at is system("PAUSE"); See this

WaltP
Posting Sage w/ dash of thyme
Moderator
10,506 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 
Not bad, although it's still not formatted properly . By the way, what does cin.clear(); do? You might want to look it up. Another thing to look at is system("PAUSE"); See this


My understanding re cin.clear() is that if the cin fails (eof or mismatch of data) then further access or use of cin is prevented; to avoid this use the clear() method.

I guess you're probably suggesting that in this particular case it's not needed. Looking at the code I can't see how a mis-match of data cin >> ch could occur and I don't think EOF is an issue either. I hope I haven't embarrassed myself with this answer or response.

Taking this a step further in relation to cin.clear(). If the receiving variable is of a numeric type is that when cin.clear() would be considered in fixing up erroneous data entries.

superjacent
Junior Poster in Training
66 posts since Nov 2007
Reputation Points: 11
Solved Threads: 3
 
My understanding re cin.clear() is that if the cin fails (eof or mismatch of data) then further access or use of cin is prevented; to avoid this use the clear() method.


True. So what error are you expecting that needs to be cleared at this point?I guess you're probably suggesting that in this particular case it's not needed. Looking at the code I can't see how a mis-match of data cin >> ch could occur and I don't think EOF is an issue either. I hope I haven't embarrassed myself with this answer or response.
That's what I'm suggesting, yes. And you have definitely NOT embarrassed yourself. It's a correct analysis.Taking this a step further in relation to cin.clear(). If the receiving variable is of a numeric type is that when cin.clear() would be considered in fixing up erroneous data entries.
Actually, no. All cin.clear() does is clear the error flags. If they were set, it does not fix any data entries. The way you're using it, the error is simply cleared and ignored. You never test for one, so you don't even know it happened.

What you suggested above is "If the receiving variable is of a numeric type" and you type in a letter instead, cin.clear() magically changes the letter to a digit. What in fact happens is the error flags are set, nothing is loaded into the variable (previous value remains unchanged), and the letter stays in the input stream for the next cin .

WaltP
Posting Sage w/ dash of thyme
Moderator
10,506 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

Actually, no. All cin.clear() does is clear the error flags. If they were set, it does not fix any data entries. The way you're using it, the error is simply cleared and ignored. You never test for one, so you don't even know it happened.

What you suggested above is "If the receiving variable is of a numeric type" and you type in a letter instead, cin.clear() magically changes the letter to a digit. What in fact happens is the error flags are set, nothing is loaded into the variable (previous value remains unchanged), and the letter stays in the input stream for the next cin .


The above makes sense and is 100% consistent with what I've read though I know I wasn't too clear with my explanation.

Thanks for the advice, and everyone else as well, it's really helped.

superjacent
Junior Poster in Training
66 posts since Nov 2007
Reputation Points: 11
Solved Threads: 3
 

the code actually has a bug, for example you've entered something like this: c2,
the program will behave unexpectedly, how to remedy this?

jade09091990
Newbie Poster
3 posts since Apr 2008
Reputation Points: 10
Solved Threads: 0
 
the code actually has a bug, for example you've entered something like this: c2, the program will behave unexpectedly, how to remedy this?


Good pick up. It appears that the variable ch needs to be checked prior to the switch statement. I've modified my original program that I posted at the top of this thread. What needed to be done is simply make sure that the next character was a newline, if it was then only a single character was input. If the next character wasn't a newline then something like c2 was entered.

Here's the code:

// chap06q03.cpp  
// C++ Primer Plus, Fifth Edition
// Chapter 6, Page 276.
// Programming Exercise # 3
// 4 Dec, 2007.
// 15 Apr, 2008 - modified - disregarding c2 etc.

#include <iostream>

int main()
{
    using namespace std;
    char ch;
    char msg[] = "\nPlease enter  c, p, t or g: ";
    bool invalid = true;
	
    cout << "Please enter on of the following choices:\n\n";
    cout << "c) carnivore        p) pianist\n";
    cout << "t) tree             g) game\n";
	
    while (invalid)
    {
        cin >> ch;
        if ((ch != 'c') && (ch != 'p') && (ch != 't') && (ch != 'g'))
        {
            while (cin.get() != '\n')
                continue;
            cout << msg;
        }
        else
            if (cin.get() == '\n')
                 invalid = false;
            else
            {
                while (cin.get() != '\n')
                    continue;
                cout << msg;
            }
    }
    switch (ch)
    {
        case 'c' : cout << "Option 'c' selected"; break;
        case 'p': cout << "Option 'p' selectd";break;
        case 't' : cout << "Option 't' selected";break;
        case 'g': cout << "Option 'g' selected"; break;
        default : cout << "It will never get her"; break;
    }
    // exit routine
    cout << "\n\n...Press ENTER to Exit System...";
    cin.get();
    return 0;
}

Given some time I'm sure the above program can be smoothed out, but at least it demonstrates only accepting a single character (not using strings and other methods). As it stands now, clearly there are a couple of snippets which are candidates to be functions.

superjacent
Junior Poster in Training
66 posts since Nov 2007
Reputation Points: 11
Solved Threads: 3
 

[code]well, thanks. it is a great help to me. I really find it hard before. thanks[code/]

jade09091990
Newbie Poster
3 posts since Apr 2008
Reputation Points: 10
Solved Threads: 0
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You