CS 176, Introduction to Computer Science II

Lab Assignment 1 Answer


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.

$
There are a number of ways you can fix this problem, depending on what you know. Perhaps the simplest, although somewhat cumbersome, way to fix the problem is to change the 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));
  }
Most people who got this lab assignment wrong messed up 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');
  }
Why doesn't this work?

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);
  }
What's wrong here?

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');
  }
What's wrong with this?

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);
  }
Another, simpler, fix along the same line is to convert the character to lower case in the main-routine while loop:
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.