I'm making a program that is supposed to count vowels. I made a char array and via if-statement I'm checking each element of it:
for( i=0 ; sent[i]!='\0' ; i++)
{
if (sent[i] = ='A'||'a'||'E'||'e'||'I'||'i'||'O'||'o'||'u')
{ vow++;
}
}
Now when I'm typing "My name is Arsal" on console, it is giving output "16 vowels" which is actually the number of all alphabetic characters along with spaces in above sentence.
When I'm removing "OR(s)"
if (sent[i] = ='A' /*||'a'||'E'||'e'||'I'||'i'||'O'||'o'||'u' */)
{ vow++;
}
the program is giving the correct output of "1" in above sentence.
This is the complete program:
#include<stdio.h>
#include<conio.h>
#include<string.h>
main()
{
int vow=0;
char sent[100];
printf("Enter sentence ; \n");
gets(sent);
printf("\n");
int i,j;
for(i=0 ; sent[i]!='\0';i++)
{
if (sent[i] == 'A'||'a'||'E' || 'e' || 'O' ||'o'||'I'||'i' ||'U' ||'u')
{
vow++;
}
}
printf("\n No.of vowels = %d",vow);
getch();
}
Please tell me the reason.
The format of your "or"s are incorrect...
Instead of
if ( sent[i] == 'A' || 'a' || 'e' .... etc
It needs to be:
if ( sent[i] == 'A' || sent[i] == 'a' || sent[i] == 'e' ... etc
Your expression:
sent[i] == 'A'||'a'||'E' || 'e' || 'O' ||'o'||'I'||'i' ||'U' ||'u'
will evaluate to non-zero (that is a true value) for every value of i.
What you seem to want is something like:
if (strchr("AEIOUaeiou", sent[i])) {
++vow;
}
Keep in mind that In C, all non-zero integers are considered as true and 0 is considered to be false.
So, here:
sent[i] == 'A'||'a'||'E' || 'e' || 'O' ||'o'||'I'||'i' ||'U' ||'u'
sent[i] == 'A' will be checked first. It is a condition that compares sent[i] with 'A' and returns 1 if they are equal and 0, if they aren't.
Now, the rest of the stuff ('a' , 'E' etc) are just positive integers (See the ASCII table). And these evaluate to true as they are non-zero.
When at least one of the operands of || are true, the entire condition becomes true (See the truth table of Logical OR).
Hence, the body of the if gets executed whatsoever.
The fix for this is given in other answers.
You can use lowerto and a switch case
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include <ctype.h>
main()
{
int vow=0 ;
char sent[100];
printf("Enter sentence ; \n");
fgets(sent, sizeof(sent), stdin);
printf("\n");
int i;
for(i=0 ; sent[i]!='\0';i++)
{
switch (tolower(sent[i])) {
case 'a':
case 'e':
case 'o':
case 'i':
case 'u':
vow++;
}
}
printf("\n No.of vowels = %d",vow);
getch();
}
This works
#include<stdio.h>
#include<conio.h>
#include<string.h>
int main( )
{
int vow = 0;
char sent[100];
printf( "Enter sentence ; \n" );
gets( sent );
printf( "\n" );
int i, j;
char c;
for ( i = 0; sent[i] != '\0'; i++ )
{
// if (sent[i] == 'A'||'a'||'E' || 'e' || 'O' ||'o'||'I'||'i' ||'U' ||'u')
c = toupper( sent[i] );
if ( c == 'A' || c == 'E' || c == 'I' || c == 'O' || c == 'U' )
{
vow++;
printf( "\n%c is vowel", sent[i] );
}
}
printf( "\n No.of vowels = %d", vow );
getch( );
}
Related
So, my code actually works perfectly when I use function that checks for special characters in string by explicitly giving symbols:
int isSpecialCharacter(char str[], int n)
{
for(int i=0; i<n;i++)
{
if (str[i] == '!' || str[i] == '#' || str[i] == '#' || str[i] == '$' || str[i] == '%' || str[i] == '^' || str[i] == '(' || str[i] == ')')
{
return 1;
}
return 0;
}
}
However, in the below code I am not able to get my code to find special characters in string using ASCII values. I want to understand what am I doing wrong. In the below code, I have my main() also included that prompts the user to input string.
#include <stdio.h>
#include <string.h>
char str[30][30];
char test[100];
int myindex = 0;
int isSpecialCharacter(char str[], int n)
{
for(int i=0; i<n;i++)
{
if (str[i] == 33 || str[i] == 35 || str[i] == 36 || str[i] == 37 || str[i] == 40 || str[i] == 41 || str[i] == 64)
{
return 1;
}
return 0;
}
}
int main()
{
printf("Please enter 10 strings below: \n");
while(myindex < 10)
{
printf("Enter string %d: ", myindex+1);
fgets(str[myindex], 500, stdin);
strcpy(test, str[myindex]);
int t_size = strlen(test);
if (strlen(str[myindex])<2||strlen(str[myindex])>26)
{
printf("Enter string that is between 2 and 25");
continue;
}
else if(isSpecialCharacter(test, t_size) == 1)
{
printf("Your string has some special characters. \n");
continue;
}
else
{
myindex++;
}
}
return 0;
}
EDIT:
I have included the variable declarations and replaced the code where I use symbols to check for special characters. Thank you.
EDIT2:
These are the characters that I want to look for: : ’!’, ’#’, ’#’, ’$’, ‘%’, ‘^’, ’(’, or ’)’. Not spaces.
Both your functions won't work as you've written them.
The main problem is that the for loop returns after each loop cycle, so you never check beyond the first cycle.
You should move the return 0 statement to the end of the function, then it will work as expected.
int isSpecialCharacter(char str[], int n)
{
for (int i = 0; i < n; i++)
{
if (str[i] == 33 || str[i] == 35 || str[i] == 36 || str[i] == 37 || str[i] == 40 || str[i] == 41 || str[i] == 64)
{
return 1;
}
}
return 0;
}
Test
I've tested the solution with the following input:
test1
test2
test)
test(
test3
test4
test5
test#
test6
test7
test!
test8
test9
test10
And it works. You can see the result there: https://godbolt.org/z/67Px14z75
As suggested from other users in the comment section, using decimal values to refer to characters is a bad practice™ and you should stick with the '#' notation.
Your return 0; is incorrect:
int isSpecialCharacter(char str[], int n) {
for(int i=0; i<n;i++)
{
if (str[i] == '!' || str[i] == '#' || str[i] == '#' || str[i] == '$' || str[i] == '%' || str[i] == '^' || str[i] == '(' || str[i] == ')')
{
return 1;
}
return 0;
}
}
On the very first loop, your function returns either 1 or 0. You only want to return 0 (false) if the loop completes without finding the character you're looking for.
int isSpecialCharacter(char str[], int n)
{
for(int i=0; i<n;i++)
{
if (str[i] == '!' || str[i] == '#' || str[i] == '#' || str[i] == '$' || str[i] == '%' || str[i] == '^' || str[i] == '(' || str[i] == ')')
{
return 1;
}
}
return 0;
}
I'm not going to try to write your code...
if( isSpecialCharacter()
is equivalent to:
if( strpbrk( test, "abqmz" ) != NULL )
(except that the latter has been proven to work...)
If a, b, q, m, z appear in the string, then the if condition is true...
Learn the standard library instead of spending time badly reinventing it...
EDIT:
Here is how an experienced programmer might write that functionality now that you've decoded the decimal ASCII values. (Don't expect the next programmer who reads your code to reach for their ASCII table...)
char spcl[] = "!##$%^()";
if( strpbrk( test, spcl ) != NULL ) {
// Do something because condition is true
NB: if you need to make either \ or " special inside a string, you must 'escape' either of those characters with an 'extra' backslash. Eg:
char spcl[] = "\\!##$%^(\")"; // notice '\\' and '\""
If that looks too much like "bad language", you can construct your own string (ENSURING(!) that it is null terminated.)
char spcl[] = { '\\', '!', '#', '#', '$', '%', '^', '(', '\"', ')' '\0' };
And...
char str[30][30];
/* Skipping ahead */
printf("Enter string %d: ", myindex+1);
fgets(str[myindex], 500, stdin); // 500!!! ????
is simply looking for trouble...
The position of "return 0" is not correct.
It should come after the end of "for loop"
so I have been working on my assignment and I can't figure out how to put if...else statement in my do..while loop because want I run the program it doesn't loop. the output is like this.
[this the output that I got][1]
#include <stdio.h>
#include <ctype.h>
int main(void){
char alphabet;
char confirm;
int lowercase_vowel, uppercase_vowel;
int a =1;
do{
printf("Enter an alphabet: ");
scanf("%c", &alphabet);
// evaluates to 1 if variable c is a lowercase vowel
lowercase_vowel = (alphabet == 'a' || alphabet == 'e' || alphabet == 'i' || alphabet == 'o' || alphabet == 'u');
// evaluates to 1 if variable c is a uppercase vowel
uppercase_vowel = (alphabet == 'A' || alphabet == 'E' || alphabet == 'I' || alphabet == 'O' || alphabet == 'U');
if(!isalpha(alphabet))
{
printf("Error! Non-alphabetic character.\n");
}
else if(lowercase_vowel || uppercase_vowel)
{
printf("%c is a vowel.\n", alphabet);
}
else
{
printf("%c is a consonant.\n", alphabet);
}
printf("\nif u want to proceed enter 1, if not enter 0\n");
scanf("%d", &a);
}while( a == 1);
}
``
[1]: https://i.stack.imgur.com/oRK1G.png
do
{
// code
}while (a = 1);
This will create an infinite loop, because it will assign 1 to a, and because a is now a nonzero value, the condition is true, and it will loop again:
Maybe what you want is:
do
{
// code
}while (a == 1); // comparison, not assignment
Also:
scanf("%d", a);
should be:
scanf("%d", &a);
Q : Write a program to count the number of occurrences of any two vowels in succession in a line of text. For example the following sentence :
"Please read the application and give me gratuity"
Such occurrences in the sentence are :- "ea" , "ea" , "io" , "ui". Ultimately the question is to count the number of such occerrences in the line which is a user input string.
Problem : My program is just recieve a line but did not give any output.
It's my first question in stackoverflow. I am a beginner in programming.
My code:
# include <stdio.h>
int main () {
char line[100];
printf("\nEnter a line\n");
gets(line);
//printf("You entered : %s\n", line);
char A,E,I,O,U,a,e,J,o,u;
A = 'A';
E = 'E';
I = 'I';
O = 'O';
U = 'U';
a = 'a';
e = 'e';
J = 'i';
o = 'o';
u = 'u';
int occurence =0,i =0 ;
while (line[i] =! '\0'){
if((line[i] == A || E || I || O || U || a || e || J || o || u) && (line[i+1] == a || e || J || o || u)){
occurence++;
}
i++;
}
printf("Number of occurence of any two vowels in succession in the line is : %d\n", occurence);
return 0;
}
Your code has multiple issues, some of which are:
You use gets to read the string. This function is now at least deprecated (I think it was even removed from recent versions of the standard library) because it is unsafe. Use fgets instead!
You use the || operator wrong - this was already pointed out in mediocrevegetable1's comment.
You could use a code similar to this one to solve your problem. The code contains comments, so it should be easy to understand. However, if this is a homework or project for school, do NOT use this exact code, as this would most likely be considered plagiarism!
#include <stdio.h>
#include <ctype.h>
#define STRLEN 100
int main () {
char line[STRLEN];
char* ch;
char incrementIfVowel;
int occurences;
/* Read line */
printf("\nEnter a line\n");
fgets(line, STRLEN, stdin);
/* Init variables */
incrementIfVowel = 0;
occurences = 0;
/* Iterate through characters */
for (ch = line; *ch != '\0'; ch++) {
/* Test if the current character is a vowel. Three cases can occur: */
if (toupper(*ch) == 'A' || toupper(*ch) == 'E' || toupper(*ch) == 'I' || toupper(*ch) == 'O' || toupper(*ch) == 'U') {
if (incrementIfVowel == 1) {
/* Case 1: The current character is a vowel, and its predecessor was also a vowel */
incrementIfVowel = 0;
occurences++;
}
else {
/* Case 2: The current character is a vowel, but its predecessor was not a vowel or it was the second vowel in a row */
incrementIfVowel = 1;
}
}
else {
/* Case 3: The current character is not a vowel */
incrementIfVowel = 0;
}
}
/* Print result */
printf("Number of occurence of any two vowels in succession in the line is : %d\n", occurences);
return 0;
}
There are 3 main issues with your code:
gets(line);
gets doesn't check the length of the buffer and for this reason, is susceptible to buffer overflows. gets had been deprecated since C99 and was removed in C11. You're probably compiling with an older version of the standard; I'd suggest you switch to newer versions. As for an alternative, see fgets.
while (line[i] =! '\0'){
=! is a typo. Replace it with !=
if((line[i] == A || E || I || O || U || a || e || J || o || u) && (line[i+1] == a || e || J || o || u))
This will always evaluate to true because || doesn't chain like that. Ideally, you should put this in a function:
_Bool is_vowel(char ch)
{
return toupper(ch) == 'A' || toupper(ch) == 'E' || toupper(ch) == 'I' || toupper(ch) == 'O' || toupper(ch) == 'U';
}
toupper is defined in <ctype.h> so be sure to include that. You could also shorten this behemoth of a line with return strchr("AEIOUaeiou", ch), but if you haven't used strchr and are not comfortable with using it yet, that's okay.
Modifying only the incorrect parts, your final code will can look something like this:
#include <stdio.h>
#include <ctype.h>
_Bool is_vowel(char ch)
{
return toupper(ch) == 'A' || toupper(ch) == 'E' || toupper(ch) == 'I' || toupper(ch) == 'O' || toupper(ch) == 'U';
}
int main () {
char line[100];
printf("\nEnter a line\n");
fgets(line, sizeof line, stdin);
int occurence = 0, i = 0;
while (line[i] != '\0') {
if(is_vowel(line[i]) && is_vowel(line[i + 1]))
occurence++;
i++;
}
printf("Number of occurence of any two vowels in succession in the line is : %d\n", occurence);
return 0;
}
An example of running this:
Enter a line
Please do something about the bee hive and then eat some meat
Number of occurence of any two vowels in succession in the line is : 5
(5 because Pl<ea>se do something ab<ou>t the b<ee> hive and then <ea>t some m<ea>t)
i should realize two very similar functions but i am having problems.
I have to read the string "username", this string can only contain letters (upper and lower case) and spaces.
I have to read the string "key", this string can only contain letters (upper and lower case) and numbers.
If the guidelines are not followed, the user must be able to retrieve the input.
Unfortunately, I cannot use special libraries (only stdio and stdlib).
I realized this:
void checkString(char *i){
int cont;
do {
scanf("%s", i);
if (checkStrLen(6, 6, i) != 0) { //function that controls the size of the string (min,max,string)
for(cont=0; cont<6;){
if((i[cont]>='0' && i[cont]<='9')||
(i[cont]>='A' && i[cont]<='Z')||
(i[cont]>='a' && i[cont]<='z')){
cont++;
}else{
printf("Not valid character");
printf("Try again");
}
}
}else{
printf("\nToo large string");
printf("\nTry again");
}
}while(1);
}
I was thinking of doing something similar.
For the first problem I would replace (i[cont]>='0' && i[cont]<='9') with (i[cont]==' ').
the problem is that I don't understand how to get out of the for if I find a forbidden character during the loop.
I was thinking of using a break, but that would get me out of the whole function.
any advice?
PS how does the function look like? can it be okay or is it completely wrong?
I think the do while loop is not necessary here. do the scanf and get user input first then call checkString. Inside checkString keep your if else statement.
char checkString(char *i){
int cont;
if (checkStrLen(6, 6, i) != 0) { //function that controls the size of the string (min,max,string)
for(cont=0; cont<6;){
if((i[cont]>='0' && i[cont]<='9')||
(i[cont]>='A' && i[cont]<='Z')||
(i[cont]>='a' && i[cont]<='z')){
cont++;
}else{
printf("Not valid character");
printf("Try again");
return i;
}
}
}
else{
printf("\nToo large string");
printf("\nTry again");
}
}
#include <stdio.h>
#define MAXSIZE 100
#define SIZELIM 6
#define true 1
#define false 0
// Returns length of string
// If possible, use strlen() from <string.h> instead
int strlen(char *str) {
char i;
for (i = 0; str[i] != 0 && str[i] != '\n'; i++);
return i;
}
// Returns 1 if strings are equal
// If possible, use strcmp() from <string.h> instead
int streq(const char *x, const char *y) {
char chrx = 1, chry = 1, i;
for (i = 0;
chrx != 0 && chry != 0 && chrx == chry;
chrx = x[i], chry = y[i], i++);
return chrx == chry;
}
// Returns 1 if chr is number or letter
// If possible, use isalnum() from <ctype.h> instead
int isalnum(const char chr) {
return (chr >= '0' && chr <= '9' ||
chr >= 'A' && chr <= 'Z' ||
chr >= 'a' && chr <= 'z');
}
// Checks if string contains numbers and letters only
int isvalid(const char *str) {
int valid = true;
for (int i = 0; str[i] != 0 && str[i] != '\n'; i++) {
if (!isalnum(str[i])) {
valid = false;
break;
}
}
return valid;
}
// Main
int main(void) {
char str[MAXSIZE];
for (;;) {
printf("> ");
fgets(str, MAXSIZE, stdin);
if (streq(str, "quit\n"))
break;
if (strlen(str) > SIZELIM || !isvalid(str)) {
if (strlen(str) > SIZELIM)
puts("String too large");
else if (!isvalid(str))
puts("Not a valid string");
puts("Try again"); }
}
return 0;
}
You can code those functions that you cannot import:
int letters_and_spaces(char c)
{
return c == ' ' || C >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
}
int letters_and_numbers(char c)
{
return c >= '0' && c <= '9' || C >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
}
And to use scanf to read spaces you can't use %s. You could change to:
scanf("%100[^\n]*c", i);
BE CAREFUL: I've put 100, supposing i has enough space for that. It will read up to 100 characters (or as many as the number you put there) or until find the \n.
I'm new to C, and I'm trying to improve a program's source code that I found in a book. I noticed that the source code contains a lot of "else if" conditions but has the same results, so I tried to compress them into a smaller code using || operator in the if function.
1st code:
#include <stdlib.h>
#include <stdio.h>
int main(){
char card_name[3];
puts("Enter the card_name: ");
scanf("%2s", card_name);
int val = 0;
if (card_name[0] == 'K'){
val = 10;
} else if (card_name[0] == 'Q'){
val = 10;
} else if (card_name[0] == 'J'){
val = 10;
} else if (card_name[0] == 'A'){
val = 11;
} else {
val = atoi(card_name);
}
printf("The card name value is %i\n", val);
return 0;
}
My improvement:
#include <stdlib.h>
#include <stdio.h>
int main(){
char card_name[3];
puts("Enter the card_name: ");
scanf("%2s", card_name);
int val = 0;
if (card_name[0] == 'K' || 'Q' || 'J' ){
val = 10;
} else if (card_name[0] == 'A'){
val = 11;
} else {
val = atoi(card_name);
}
printf("The card name value is %i\n", val);
return 0;
}
The problem with mine: When I write any another value it always prompt 10. What should I do ?
The issue is in C anything that is not 0 is a truthy value so in your code you have if (card_name[0] == 'K' || 'Q' || 'J'). This checks if card_name[0] == 'K' but this will always evaluate to true because you have || 'Q' and C treats 'Q' as truth. Here is the proper fix
#include <stdlib.h>
#include <stdio.h>
int main(){
char card_name[3];
puts("Enter the card_name: ");
scanf("%2s", card_name);
int val = 0;
if (card_name[0] == 'K' || card_name[0] == 'Q' || card_name[0] == 'J' ){
val = 10;
} else if (card_name[0] == 'A'){
val = 11;
} else {
val = atoi(card_name);
}
printf("The card name value is %i\n", val);
return 0;
}
This is not the correct expression:
(card_name[0] == 'K' || 'Q' || 'J' )
This will be always evaluate to true because 'Q' and 'J' are not 0.
You should write:
(card_name[0] == 'K') || (card_name == 'Q') || (card_name == 'J')
if (card_name[0] == 'K' || 'Q' || 'J' ){
val = 10;
}
'Q', etc is evaluated as a truth statement and since the value of the char is not 0 will always be true
should be
if (card_name[0] == 'K' || card_name[0] == 'Q' || card_name[0] == 'J' ){
val = 10;
}
if (card_name[0] == 'K' || 'Q' || 'J' )
should be
if (card_name[0] == 'K' || card_name[0] == 'Q' || card_name[0] == 'J' )
'Q' will always evaluate to true, you need the full comparison in each or.
Check the operator precedence in you if statement. If you look here http://en.cppreference.com/w/c/language/operator_precedence, you can see, that == has higher priority than ||.
The correct if statement should be like this:
if (card_name[0] == 'K' || card_name[0] == 'Q' || card_name[0] == 'J' ){
If you are not sure, what is the operator precedence, you can use brackets like this:
if ((card_name[0] == 'K') || (card_name[0] == 'Q') || (card_name[0] == 'J') ){
Note:
Your code is not correct, because if(card_name[0] == 'K' || 'Q' || 'J' ) is understood as if(card_name[0] == 'K' || true || true) which is always true
No, as many others have pointed out, using if (card_name[0] == 'K' || 'Q' || 'J' ) is wrong, and they have also described why and how to correct it. However, if you really just want a shorter and snappier way of writing the test, you could go for a switch-statement:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char card_name[3];
puts("Enter the card_name: ");
scanf("%2s", card_name);
int val = 0;
switch (card_name[0]) {
case 'K': /* fallthrough */
case 'Q': /* fallthrough */
case 'J': val = 10; break;
case 'A': val = 11; break;
default: val = atoi(card_name);
}
printf("The card name value is %i\n", val);
return 0;
}
Note that a switch statement is not a generic replacement for if-else if in C as each case needs to be constant integer expression (expressing it sloppily, a C book will tell you the restrictions correctly).
Always keep in mind ||means one of the condition must be true to proceed . if && is used , it checks all the condition and proceeds only if all the conditions satisfy. Pretty basic info for noobies...