Code counts consonants incorrectly. How to solve this?

Viewed 82

I have to write a program that selects consonants from a string and counts them, and shows how many times each of them appeared. I wrote this code, but it also counts vowels. I don't know why.

#include <stdio.h>

int main()
{
    char str[100];
    int i, consonants;
    i = consonants = 0;
    int freq[256] = {0};

    printf("\n Please Enter any String :  ");
    scanf("%[^\n]", str);

    while (str[i] != '\0')
    {
        if ((str[i] >= 'a' && str[i] <= 'z') ||
            (str[i] >= 'A' && str[i] <= 'Z') &&
            (str[i] != 'a' || str[i] != 'A' ||
             str[i] != 'e' || str[i] != 'E' ||
             str[i] != 'i' || str[i] != 'I' ||
             str[i] != 'o' || str[i] != 'O' ||
             str[i] != 'u' || str[i] != 'U'))
        {
            consonants++;
            freq[str[i]]++;
        }
        i++;
    }
    printf("\n Number of Consonants in this String = %d", consonants);

    for (i = 0; i < 256; i++)
    {
        if (freq[i] != 0)
        {
            printf("\nThe frequency of %c is %d", i, freq[i]);
        }
    }
    return 0;
}

This is output:

Please Enter any String :  We strive to achive peace
Number of Consonants in this String = 21
The frequency of W is 1
The frequency of a is 2
The frequency of c is 2
The frequency of e is 5
The frequency of h is 1
The frequency of i is 2
The frequency of o is 1
The frequency of p is 1
The frequency of r is 1
The frequency of s is 1
The frequency of t is 2
The frequency of v is 2
3 Answers

I just wanted to let you know that you can get rid of the huge if condition by using the standard functions isalpha(), defined in ctype.h, and strchr(), defined in strng.h.

You can change the whole condition to just

if( isConsonant(str[i]) )

With isConsonant() defined as follows

int isConsonant( char c )
{
    static char vowels[] = "aeiouAEIOU";

    if( ialpha(c) && strchr(vowels, c) == NULL ) {
        return 1;
    }
    else {
        return 0;
    }
}

This part of your condition (which because of the rest of the logic influences the whole outcome) will always be true:

str[i] != 'a' || str[i] != 'A'

That is why all letters are counted as consonants.

You want the negation of "is a vowel".

!(str[i] == 'a' ||
  str[i] == 'A' ||
  str[i] == 'e' ||
  str[i] == 'E' ||
  str[i] == 'i' ||
  str[i] == 'I' ||
  str[i] == 'o' ||
  str[i] == 'O' ||
  str[i] == 'u' ||
  str[i] == 'U')

which is "not(that or that or that)"
or
the logically equivalent "not that and not that and not that".

(str[i] != 'a' &&
 str[i] != 'A' &&
 str[i] != 'e' &&
 str[i] != 'E' &&
 str[i] != 'i' &&
 str[i] != 'I' &&
 str[i] != 'o' &&
 str[i] != 'O' &&
 str[i] != 'u' &&
 str[i] != 'U')

Note, I chose to discuss the logic of your code, assuming that it is interesting for you and helpful for your learning. However, I really like the other answer too, which is strong on the wheel-not-inventing philosophy. I won't explain, look there.

Full logic:

if ( ( (str[i] >= 'a' && str[i] <= 'z') ||
       (str[i] >= 'A' && str[i] <= 'Z')
     )
       /* a letter */
     &&
       /* not a vowel */
     (  str[i] != 'a' && str[i] != 'A' &&
        str[i] != 'e' && str[i] != 'E' &&
        str[i] != 'i' && str[i] != 'I' &&
        str[i] != 'o' && str[i] != 'O' &&
        str[i] != 'u' && str[i] != 'U'
     )
   )

Without the additional pair of () around "is a letter" you would get
"is a lower case or is an upper case consonant", i.e. would still be counting lower case vowels.

You just change

||(str[i] >= 'A' && str[i] <= 'Z')
&&(str[i] != 'a' || str[i] != 'A' 
||str[i] != 'e' || str[i] != 'E' 
||str[i] != 'i' || str[i] != 'I' 
||str[i] != 'o' || str[i] != 'O' 
||str[i] != 'u' || str[i] != 'U'))

to

&&(str[i] != 'a'
&& str[i] != 'A' 
&&str[i] != 'e'
&& str[i] != 'E' 
&& str[i] != 'i' 
&& str[i] != 'I' 
&& str[i] != 'o'  
&& str[i] != 'O'
&& str[i] != 'u' 
&& str[i] != 'U'))

my code:

#include <stdio.h>
#include <string.h>

int main()
{
    char str[100];
    int i=0, consonants=0;
    int vowels=0,numbers=0;
    int freq[256] = {0};

    printf("\n Please Enter any String :  ");
    scanf("%[^\n]", str);
    vowels=0,numbers=0,i=0;
    while (str[i] != '\0')
    {

       if((str[i]>= 'a'&&str[i]<= 'z') || (str[i] >= 'A' && str[i] <= 'Z')&&(str[i] != 'a' && str[i] != 'A' &&str[i] != 'e'&& str[i] != 'E' && str[i] != 'i' && str[i] != 'I' && str[i] != 'o' && str[i] != 'O'&& str[i] != 'u' && str[i] != 'U'))
      {
         consonants++;
         freq[str[i]]++;
      }
      i++;

   }
   printf("\n Number of Consonants in this String = %d", consonants);

   printf("\n\n");
   for (i = 0; i < 256; i++)
   {
       if (freq[i] != 0)
       {
           printf("\nThe frequency of %c is %d", i, freq[i]);
       }
   }
   printf("\n\n");
   return 0;
}
Related