The problem with the lab program is that it didn't recognize capital letters as
letters, which is contrary to the behavior stated in main()
:
Letter case should be ignored; that is, this program considers 'a' and 'A' to be the same characters.Here's a test case that discovers the error:
$ cat tc1 A E I O U . $ la1 < tc1 Type a letter: Vowel count: 0. Consonent count: 0. $
is_vowel()
and is_consonent()
functions to
ignore letter case:
static bool is_vowel(char letter) { // Return true of letter is a vowel, false otherwise. return (letter == 'a') || (letter == 'A') || (letter == 'e') || (letter == 'E') || (letter == 'i') || (letter == 'I') || (letter == 'o') || (letter == 'O') || (letter == 'u') || (letter == 'U'); } static bool is_consonent(char letter) { // Return true if letter is a consonent (that is, a non-vowel letter), false // otherwise. return ((('a' <= letter) && (letter <= 'z')) || (('A' <= letter) && (letter <= 'Z'))) && !is_vowel(letter)); }
is_consonent()
.
For example, this version doesn't work correctly:
static bool is_consonent(char letter) { // Return true if letter is a consonent (that is, a non-vowel letter), false // otherwise. return ('A' < letter) && (letter <= 'z'); }
The next example has essentially the same problem as the previous example:
static bool is_consonent(char letter) { // Return true if letter is a consonent (that is, a non-vowel letter), false // otherwise. return (letter >= 'a' || letter >= 'A') && (letter <= 'z' || letter 'Z') && !is_vowel(letter); }
The last example is tricky:
static bool is_consonent(char letter) { // Return true if letter is a consonent (that is, a non-vowel letter), false // otherwise. return ('a' <= letter && letter <= 'z') && !is_vowel(letter) || ('A' <= letter && letter <= 'Z'); }
A copule of people with Unix and C-C++ experience knew of the tolower()
macro, which is defined in the ctype.h
header file (see the ctype man page
for details). Using tolower()
the solution is simple and straightforward:
static bool is_vowel(char letter) { // Return true of letter is a vowel, false otherwise. letter = tolower(letter); return (letter == 'a') || (letter == 'e') || (letter == 'i') || (letter == 'o') || (letter == 'u'); } static bool is_consonent(char letter) { // Return true if letter is a consonent (that is, a non-vowel letter), false // otherwise. letter = tolower(letter); return ('a' <= letter) && (letter <= 'z') && !is_vowel(letter); }
while (!done) { cout << "Type a letter: "; cin >> letter; letter = tolower(letter); if (is_vowel(letter)) vowels = vowels + 1; else if (is_consonent(letter)) consonents = consonents + 1; else done = true; }
This fix, although simpler, is less desirable than the previous fix because it
leaves the is_vowel()
and is_consonent()
procedures broken in the
sense that they still don't recognize upper-case characters.
This page last modified on 23 May 2001.