-2

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);
}
anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • 1
    Does this answer your question? [C++ Most efficient way to compare a variable to multiple values?](https://stackoverflow.com/questions/15181579/c-most-efficient-way-to-compare-a-variable-to-multiple-values) – cigien Jul 23 '21 at 23:14

4 Answers4

3

It compares str[i] with the expression 'a' || 'e' || 'i' || 'o' || 'u', which gets evaluated to true, which value is equal to 1. Think about characters as integers, which char correspond to (in ASCII), then your expression would be 97 || 101 || ..., which is certainly true.

To make this work as intended, you need to split all comparisons:

str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o' || str[i] == 'u'
whiskeyo
  • 873
  • 1
  • 9
  • 19
1

According to the C Standard (6.5.14 Logical OR operator)

3 The || operator shall yield 1 if either of its operands compare unequal to 0; otherwise, it yields 0. The result has type int.

So this primary expression within the condition of the if statement

('a'||'e'||'i'||'o'||'u')

is always evaluates to integer 1 because at least the first operand 'a' is unequal to 0.

So in fact this if statement

if(str[i]==('a'||'e'||'i'||'o'||'u')){

is equivalent to

if( str[i] == 1 ){

and it evaluates to logical true only in one case when str[i] is equal to 1.

You need to write

if( str[i] == 'a' || str[i] == 'e'|| str[i] == 'i'|| str[i] == 'o'|| str[i] == 'u' ){

Another approach is to use the standard function strchr. For example

if ( strchr( "aeiou", str[i] ) ) {
    //...
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
1

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.

anastaciu
  • 23,467
  • 7
  • 28
  • 53
0

You probably forgot that you should use operators with two operands, so the compiler could recognize each operation and label them as True or False. use this code instead:

 
int main() {
    int k=0;
    char str[100];
      scanf("%[^\n]s",str);
    for(int i=0;i<strlen(str);i++){
        if((str[i]== 'a')||(str[i] == 'e')||(str[i] == 'i')||(str[i] == 'o')||(str[i] == 'u')){
        k++;
        }
    }
 printf("%d",k);
}```
gha7all
  • 75
  • 8