Given below is my code for finding vowels in a given string:
#include <stdio.h>
#include <string.h>
int main() {
char str[100];
int i, str_length;
//scanf("%[^\n]%*c", &str[100]);
fgets(str, sizeof(str), stdin);
str_length = strlen(str);
for (i = 0; i < str_length; i++) {
if (str[i] == 'a' || str[i] == 'e' ||
str[i] == 'i' || str[i] == 'o' ||
str[i] == 'u' || str[i] == 'A' ||
str[i] == 'E' || str[i] == 'I' ||
str[i] == 'O' || str[i] == 'U')
{
printf("Vowels in the string are: %c \n", str[i]);
}
}
return 0;
}
I just wanna know, why scanf("%[^\n]%*c",&str[100])
is not working in my code?
cause I tried executing my program multiple times using scanf
but it didn't worked.
And after using fgets
I got the desired output.
So, can anyone help me to understand, where I am wrong!!
In the scanf
function call, this &str[100]
takes a pointer to str
, makes it point to the element with the index 100 (which is past the end of the array), dereferences it and then takes the address of that (non-existing) element. This, most likely, leads to an attempt to an invalid write, which is probably caught by the operating system which terminates your program. In any case, the string is not written to the correct location.
Instead, you want the argument to point to the memory location of the first element of str
, i.e.:
scanf("%[^\n]%*c", str);
That said, using fgets
is better as it accepts an argument for the size which prevents buffer overflows. A size can also be given to scanf
, but since it is part of the format specifier it cannot be a variable; only a hardcoded constant:
scanf("%99[^\n]%*c", str);
Note that this is for 99 elements, as there needs to be room for the null-terminator (\0
) as well. See here for more info on scanf
. But again, using fgets
is less error prone and to be preferred.
Some additional advice:
main
function, using no parameters, is int main(void)
.scanf
version fails if the input is a single newline character. Both versions fail on no input. It is always a good idea the check the return values of input (and output) functions.for (i = 0; i < str_length; i++) {
char ch = tolower(str[i]);
if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u')
printf("Vowels in the string are: %c \n", str[i]);
}
strchr
, which makes the program a bit more generic and scalable (one string is more easily changed than multiple comparisons):char ch = tolower(str[i]);
if (strchr("aeiou", ch) != NULL)
printf("Vowels in the string are: %c \n", str[i]);