Search code examples
ccharlogical-or

what is wrong with this execution of OR operand in C


When I separate the str[i] with all the vowels it works, what is wrong with the current execution?

#include <stdio.h>
#include<string.h>
 
int main() {

    int k = 0;
    char str[100];

    scanf("%[^\n]s", str);

    for(int i = 0; i < strlen(str); i++){
        if(str[i] == ('a' || 'e' || 'i' || 'o' || 'u')){
           k++;
        }
     }
     printf("%d",k);
}

Solution

  • When I separate the str[i] with all the vowels it works...

    This is due to the fact that you are comparing a character with a boolean expression, which will be either 1 or 0, this comparison will never be true, str will not have any characters with 0 or 1 codes, these are non-printable control characters.

    In practical terms ('a'||'e'||'i'||'o'||'u') is equivalent to (97 || 101 || 105 || 111 || 117) these are each character's ASCII codes as an example, other encodings will have different codes, this is how your program really sees them.

    Anyway, this sequence of OR's will evaluate to 1, so let's say str[i] is 'a', the comparison will be 97 == 1, this is of course false, the same for the other vowels, so k will never be incremented.

    Of course separating the characters one by one will work because each individual comparison will now work as expected.

    If you don't like the long if you can use :

    #include <stdio.h>
    #include <string.h>
    
    int main() {
        
      int k = 0;
      char str[100];
    
      scanf("%[^\n]", str);
    
      for (int i = 0; i < strlen(str); i++) {
          switch(str[i]){
              case 'a': case 'e': case 'i': case 'o': case 'u':
                  k++;
          }
      }
      printf("%d", k);
    }
    

    Or you can use strchr as posted by Vlad.


    On a side note, scanf("%[^\n]s", str); should be scanf("%[^\n]", str);, the %[^\n] specifier doesn't need an s at the end, if you include it it means that scanf will be expecting a string ending in s.