C is hard enough without low quality programming examples
I recently read through some of the C programming examples
from Sanfoundry.
Some of the examples are well constructed while others are very poorly
constructed.
One of the bad examples I read is found under the heading of
Simple C Programs. The example purports to show how to count the number of
vowels and consonants in an input sentence.
The source code for the example follows.
/* * C program to read a sentence and count the
total number of vowels * and consonants in the sentence. */ #include
<stdio.h> void main() { char sentence[80]; int i, vowels = 0, consonants = 0,
special = 0; printf("Enter a sentence \n"); gets(sentence); for (i = 0; sentence[i] != '\0'; i++) { if ((sentence[i] == 'a' ||
sentence[i] == 'e' || sentence[i] == 'i' || sentence[i] == 'o' ||
sentence[i] == 'u') || (sentence[i] == 'A' || sentence[i] ==
'E' || sentence[i] == 'I' || sentence[i] == 'O' ||
sentence[i] == 'U')) { vowels = vowels + 1; } else { consonants = consonants + 1; } if (sentence[i] =='\t' ||sentence[i]
=='\0' || sentence[i] ==' ') { special = special + 1; } } consonants = consonants - special; printf("No. of vowels in %s =
%d\n", sentence, vowels); printf("No. of consonants in %s =
%d\n", sentence, consonants); } |
This program does not actually identify a sentence. Instead
it merely reads a single input line from stdin. The first conditional carefully
identifies the values of the vowels and then assumes anything not a vowel is a
consonant. A second conditional makes a weak attempt to find “special”
characters that are not letters, but this conditional only looks for tabs,
spaces and end of string null characters. It completely ignores punctuation and
numeric digits. Sentences often contain punctuation and numeric digits, which
are neither vowels nor consonants. The error shows in an inflated count of
consonants when an input string contains punctuation and/or numeric digits.
The example program is poorly designed and does not fulfill
the requirements expressed on the page C
Program to Count the Number of Vowels and Consonants in a Sentence - Sanfoundry.
I wrote an Ada program to achieve the same stated goals.
This program uses approximately the same number of lines of source code as the
C program while avoiding the problem of miscounting consonants.
-- Ada
program to read a line of text and count the number of vowels -- and
consonants in the text with
Ada.Text_IO; use Ada.Text_IO; procedure
Main is subtype Letter is Character with Static_Predicate => Letter in 'a'
.. 'z' | 'A' .. 'Z'; subtype Vowel is Character with Static_Predicate => Vowel in 'a' |
'e' | 'i' | 'o' | 'u' | 'A' | 'E' | 'I' | 'O' | 'U'; Line
: String (1 .. 80); vowels
: Natural := 0; consonants : Natural := 0;
Length : Natural; begin Put_Line ("Enter a sentence:"); Get_Line (Item => Line, Last =>
Length); for I in 1 .. Length loop if Line (I) in Letter then if Line (I) in Vowel then vowels := vowels + 1; else consonants := consonants + 1; end if; end if; end loop; Put_Line ("Number of vowels in " &
Line (1 .. Length) & " is" & vowels'Image); Put_Line ("Number of consonants in "
& Line (1 .. Length) & " is" & consonants'Image); end Main; |
The Ada program explicitly defines a subtype of Character
containing only English letters. It also defines a subtype of Character
defining only the vowels defined in the C program.
The first conditional in the Ada program filters out all
characters that are not letters. Within that conditional block the current
character is tested for being a vowel. If it is not a vowel then it can only be
a consonant. Both the vowel count and the consonant count are correct because
the program selected only letters and filtered out all non-letter characters.
C language philosophy
The C language expects the programmer to perform all error
checking while only providing very primitive means of specifying the correct
data conditions. Historically C has concentrated its design on execution speed
at the expense of programmer effort.
Ada language philosophy
The Ada language provides syntax tools to define subtypes of
a data type based upon either a range of values or set of values. The Ada
example above defines two subtypes of the predefined type Character. One subtype
defines the set of all lower case and upper case letters. The other subtype
defines the set of lower case and upper case letters identified as vowels.
Each of these subtypes is expressed in a very compact manner
in a single expression.
These subtypes express exactly what is a letter and what is
a vowel.
Conclusion
The C program never specifies what is a letter. The result
is a latent error in program logic which most beginning C students would be
unlikely to identify. Eliminating this error would require either a laborious
list of letters in C or a list of the numeric ranges representing lower case
letters and upper case letters. The first option greatly obscures the meaning
of the filtering by its complexity. The second option greatly obscures the
meaning of the filtering by using the numeric representation of the letters in
a compound conditional expression such as
If ((sentence[i] >= 65 && sentence[i] <= 90) ||
(sentence[i] >= 97 && sentence[i] <= 122))
The Ada equivalent is accomplished by defining the set of
values constituting a letter
subtype Letter
is Character with
Static_Predicate => Letter in 'a' ..
'z' | 'A' .. 'Z';
Followed by a simple conditional
if Line (I) in Letter then
The Ada “in” operator returns True if Line (I) is a member
of the set of values defined for Letter and False if Line (I) is not a member
of the set of values define for Letter.
The set of letters is defined as all the characters in the
range starting at ‘a’ and ending at ‘z’ and all the characters in the range
starting at ‘A’ and ending at ‘Z’. While this set defines the same values as
the C conditional example above, it does so in a very clear manner understandable
by programmers of all levels of experience, without resorting to a table of
values mapping characters to numeric representations.
The Ada program clearly specifies all the values needed to
count vowels and consonants, thereby eliminating the latent defect present in
the C program.
"y" is a vowel no?
ReplyDeletenope, just in french, sorry
DeleteIn English 'y' is only sometimes a vowel. For instance, the word "yesterday" contains two 'y's. The first 'y' is not a vowel and the second 'y' is a vowel. The letter 'w' is usually a consonant. It is a vowel only when it teams up with an 'a', 'e', or 'o' to spell a single sound—as in the words draw, few, and low. So the letter 'w' is a vowel only in the two-letter teams 'aw', 'ew', and 'ow'.
DeleteThe examples in this blog intentionally simplify the problem to use only vowels that are always vowels in English.