2

PROBLEM:

Write a C program that prompts the user to enter a string of characters terminated by ENTER key (i.e. ‘\n’) and then count the total number of the occurrence of each vowel in the string. Your program should use the following guidelines:
• Your program should declare an array of 5 integer counters, namely counter.
• Using a loop, your program should initialize each member of the array to 0.
• Each character in the string is then checked to see if it is a vowel, i.e. ‘a’, ‘e’, ‘i’, ‘o’ or ‘u’. In that case, the corresponding counter is incremented. For example if an ‘a’ is read then counter[0] is incremented, if an ‘i’ is read then counter[2] is incremented and so on.
• The entered characters could be lower or upper case.
• Your program should use a loop to printout the contents of the 5 counters.
• Lastly your program should print the total number of vowels in the string.
The result should look like: Please enter a string terminated by ENTER key:

“The brown fox jumped over the lazy dog”

counter[0] = 1
counter[1] = 4
counter[2] = 0
counter[3] = 4
counter[4] = 1

Total number of Vowels= 10

MY CODE:

#include <stdio.h>
main(){
int counter[5];
int c, i;
for(i = 0; i < 5; i++)
counter[i] = 0;
printf("Please enter a string terminated by ENTER key:\n");
while((c = getchar()) != '\n')
{
     if((counter[i] == 'a' || counter[i] == 'e' || counter[i] == 'i' || counter[i] ==
    'o' || counter[i] == 'u') ||(counter[i] == 'A' || counter[i] == 'E' || counter[i] == 
    'I' || counter[i] == 'O' || counter[i] == 'U'))
    {
        for(i = 0; i < 5; i++)
        {
            if(c == 'a' + i)
            counter[i] = counter[i] + 1;
        }
    }
}
for(i = 0; i < 5; i++)
    printf("counter[%d] = %d\n", i, counter[i]);
}

What's wrong with my counter? Thanks in advance.

durron597
  • 30,764
  • 16
  • 92
  • 150
user2990755
  • 29
  • 1
  • 5

5 Answers5

1

First of all you should put the return type for main: int ( ex: int main() ), this did not break your code but it the C standard and rises a warning from the compiler.

Chars in C take the numerical value from the ASCII encoding standard: http://upload.wikimedia.org/wikipedia/commons/1/1b/ASCII-Table-wide.svg, look at the values there ( 'a' is 97 for example), more on wikipedia : http://en.wikipedia.org/wiki/ASCII

All you do in your last for loop is compare the character to a,b,c,d,e.

What I would recommend you to do is make a switch for the character:

switch(c) {
    case 'a':
    case 'A':
        counter[0]++;
        break;
    case 'e':
    case 'E':
        counter[1]++;
        break;
    case 'i':
    case 'I':
        counter[2]++;
        break;
    case 'o':
    case 'O':
        counter[3]++;
        break;
    case 'u':
    case 'U':
        counter[4]++;
        break;
}

Alternatively, you could make five if statements.

It should work fine now.

Lawrence Dol
  • 59,198
  • 25
  • 134
  • 183
eduardtm
  • 76
  • 6
  • 1
    +1: I think this is the cleanest solution to the specific problem. The OP will, of course, have to apply this switch appropriately in a loop over the input characters. – Lawrence Dol Mar 03 '14 at 22:36
  • But note that the default case is omitted, which is widely considered bad style. – Lawrence Dol Mar 03 '14 at 22:44
1

I think this is what you are trying to do:

printf("Please enter a string terminated by ENTER key:\n");
while((c = getchar()) != '\n')
{
    if (c=='a' || c=='A')
        counter[0]++;
    else if (c=='e' || c=='E')
        counter[1]++;
    else if (c=='i' || c=='I')
        counter[2]++;
    else if (c=='o' || c=='O')
        counter[3]++;
    else if (c=='u' || c=='U')
        counter[4]++;
}
for(i = 0; i < 5; i++)
    printf("counter[%d] = %d\n", i, counter[i]);

OR using switch:

printf("Please enter a string terminated by ENTER key:\n");
while((c = getchar()) != '\n')
{
    switch(c)
    {
        case 'a':
        case 'A': counter[0]++;
                  break;
        case 'e':
        case 'E': counter[1]++;
                  break;
        case 'i':
        case 'I': counter[2]++;
                  break;
        case 'o':
        case 'O': counter[3]++;
                  break;
        case 'u':
        case 'U': counter[4]++;
                  break;
        default: break;
    }
}
for(i = 0; i < 5; i++)
    printf("counter[%d] = %d\n", i, counter[i]);
Raging Bull
  • 17,348
  • 12
  • 44
  • 49
  • is it possible to do this with an array of 5 integer counters? why must you use char? – user2990755 Mar 03 '14 at 07:21
  • -1 for using [`gets()`](http://www.freebsd.org/cgi/man.cgi?gets%283%29): _The `gets()` function cannot be used securely. Because of its lack of bounds checking, and the inability for the calling program to reliably determine the length of the next incoming line, the use of this function enables malicious users to arbitrarily change a running program's functionality through a buffer overflow attack. It is strongly suggested that the `fgets()` function be used in all cases._ – moooeeeep Mar 04 '14 at 07:52
  • @moooeeeep: Yup, you are right. Since gets() is dangerous, changed my answer. Thanks! – Raging Bull Mar 04 '14 at 09:39
1

(just for fun, my answer)

int main(void)
{
    int counter[5] = {0};
    int *i, c;

    printf("Please enter a string terminated by ENTER key:\n");
    while(i = counter, (c = getchar()) != '\n')
    {
        switch(c)
        {
          default: continue;
          case 'U'+' ': case 'U': ++ i;
          case 'O'+' ': case 'O': ++ i;
          case 'I'+' ': case 'I': ++ i;
          case 'E'+' ': case 'E': ++ i;
          case 'A'+' ': case 'A': ++*i;
        }
    }

    for(c = 0; c < 5;

    printf("counter[%d] = %d\n", c, counter[c++]));

    return 0;
}
abelenky
  • 58,532
  • 22
  • 99
  • 149
  • Way too obtuse. Simple and obvious is *always* better than "clever" and obtuse. – Lawrence Dol Mar 03 '14 at 22:38
  • As I said, "just for fun". If he wants homework help, I can get creative. :) – abelenky Mar 03 '14 at 22:39
  • Teaching someone to be a "clever" C programmer does no-one any good - not the OP and certainly not the poor sap that ends up maintaining his code. – Lawrence Dol Mar 03 '14 at 22:42
  • 1
    Programming should be ***fun***. While my professional code is as clean and simple as I can make it, occasionally one should indulge in creative writing, such as this! – abelenky Mar 03 '14 at 22:46
  • 1
    @SoftwareMonkey It's possible to be both correct and missing the point. Yes, this code is absolutely absurd, and should never, ever be used in a professional context. However, this code incorporates a lot of essential details about how the C language works, and programmers are only as good as their understanding of their tools. I would not want to work with a programmer who couldn't figure this code out. As a learning exercise, it's quite valuable. – Kennet Belenky Mar 03 '14 at 23:23
  • Spoken like someone who has never had to maintain code by someone who writes this kind of code. But whatever. – Lawrence Dol Mar 04 '14 at 03:01
0

while((c = getchar()) != '\n') { if((counter[i] == 'a' || counter[i] == 'e' || counter[i] == 'i' || counter[i] == 'o' || counter[i] == 'u') ||(counter[i] == 'A' || counter[i] == 'E' || counter[i] == 'I' || counter[i] == 'O' || counter[i] == 'U')) { for(i = 0; i < 5; i++) { if(c == 'a' + i) counter[i] = counter[i] + 1; } } }

I feel the logic in this code may be wrong because, you have initialized your counter[0] with 0 and then you are comparing it with 'a' or 'A' but not the char c, so use

while((c = getchar()) != '\n') { if(c == 'a' || c == 'A') { i = 0; counter[i] =+ 1; } else if( c == 'i' || c == 'I' ) { i = 1; counter[i] =+ 1; } ...//and so on
}

Trilok M
  • 601
  • 7
  • 18
  • Why assign `i`, only to use it once in each branch?? – Lawrence Dol Mar 03 '14 at 22:37
  • because its mentioned • Each character in the string is then checked to see if it is a vowel, i.e. ‘a’, ‘e’, ‘i’, ‘o’ or ‘u’. In that case, the corresponding counter is incremented. For example if an ‘a’ is read then counter[0] is incremented, if an ‘i’ is read then counter[2] is incremented and so on. – Trilok M Mar 04 '14 at 04:31
0

Apparantly none of the other answerers so far have noticed these possibilities to improve the code:

  • Define the vowels as a string and write a function that returns the index of the vowel in that string (or -1 in case of a not-a-vowel error).
  • Convert the character to lowercase before doing the comparison. This is a very common approach to achieve case insensitive behavior.
  • You should also check for EOF as an exit condition for your loop.

I think, what you need is something like this:

#include <stdio.h>
#include <ctype.h>

const char vowels[] = "aeiou";

int findvowel(char c) {
    int i;
    c = tolower(c);
    for (i=0; vowels[i]; i++)
        if (vowels[i] == c)
            return i;
    return -1;
}

int main() {
    char c;
    int i, sum;
    int counter[sizeof(vowels)] = {0};
    while (c=getchar(), c != EOF && c != '\n') {
        i = findvowel(c);
        if (i != -1)
            counter[i] += 1;
    }
    printf("having found these vowels:\n");
    for (i=0, sum=0; vowels[i]; i++) {
        printf("'%c': %d\n", vowels[i], counter[i]);
        sum += counter[i];
    }
    printf("total: %d %s\n", sum, sum != 1 ? "vowels" : "vowel");
    return 0;
}
moooeeeep
  • 28,315
  • 14
  • 88
  • 166