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...
Related
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);
Sorry if the title is a bit confusing, I'll try to explain better here.
So basically I'm trying to write a program where the user inputs a phone number in an alphabetic form and it then gets translated in a numeric form. Like this:
Enter phone number: CALLATT
22555288
Where 2=ABC, 3=DEF, 4=GHI, 5=JKL, 6=MNO, 7=PRS, 8=TUV, 9=WXY
Also if the phone number input contains chars that are not alphabetical they should be left as they are. Which means:
Enter phone number: 1-800-COL-LECT
1-800-265-5328
Now, I know that this could be solved very easily using strings and arrays but I'm not supposed to use them for this exercise. I wrote this code:
#include <stdio.h>
int main() {
char two = '2', three = '3', four = '4', five = '5', six = '6',
seven = '7', eight = '8', nine = '9';
char num;
printf("Enter a phone number: ");
do {
num = getchar();
if(num == 'A' || num == 'B' || num == 'C'){
num = two;
}
else if(num == 'D' || num == 'E' || num == 'F'){
num = three;
}
else if(num == 'G' || num == 'H' || num == 'I'){
num = four;
}
else if(num == 'J' || num == 'K' || num == 'L'){
num = five;
}
else if(num == 'M' || num == 'N' || num == 'O'){
num = six;
}
else if(num == 'P' || num == 'R' || num == 'S'){
num = seven;
}
else if(num == 'T' || num == 'U' || num == 'V'){
num = eight;
}
else if(num == 'W' || num == 'X' || num == 'Y'){
num = nine;
}
printf("%c", num);
}while(getchar() != '\n');
return 0;
}
Which doesn't obviously work. I mean, it works just fine if the user inputs a single char but not if the input is composed by more than one char. I can't really get my head around this... I know why and where my code is wrong but I can't really find an effective solution to solve the problem without using arrays.
Any help? Thanks a lot :)
Try
int num = getchar();
do {
/* your if / else / if train */
printf("%c", num);
} while ((num = getchar()) != '\n'); // assign and compare
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( );
}
for example when I type in a string "Hello", when I press 'a' it should print "There are 2 vowels." Instead, it says there are 0. I'm new to programming and this is the first language I am learning. Help?
/*
Student: Josiah Eleazar T. Regencia
Course: BSIT 1
Subject: SCS 101
Professor: Daniel B. Garcia
Problem definition:
Write a menu program that will count the vowels and consonants in the string
*/
#include <stdio.h> //printf and scanf functions
#include <string.h> //string functions
#include <stdlib.h>
#include <conio.h>
#define PROMPT "Type in a word, a phrase, or a sentence." //instucts the user
/*
Declaring the function for the user's menu
*/
void menu();
/*
Declaration of function needed to count the vowels in the string
*/
int vowel_count(char *stringInput); //declaring the function to count the vowels sounds
/*
Declaration of function needed to count the consonants in the stringn
*/
int consonant_count(char *stringInput); //declaring the functions to count the consonant sounds
/*
Declaring the function needed to convert the streeting to uppercase
*/
int uppercase(char *stringInput);
/*
Declaring the function needed to convert the streeting to uppercase
*/
int lowercase(char *stringInput);
int main () {
char userInput[100]; // the string the user inputs
char commandKey[1]; //this key is for the menu
char newInput[100]; //this is for the new input to user will put in
int stringLength; //to identify the length of the string
/*
Variables for counting the vowels and consonants
*/
int consonantCount;
printf("%s\n\n", PROMPT); //instucts the user
gets(userInput);
stringLength = strlen(userInput); //gets the length of the string
//fgets(userInput, 100, stdin);
/*if(stringLength > 0 && userInput[stringLength - 1] == '\n') {
userInput[stringLength - 1] ='\0';
}*/
menu(); //prints out the menu for the user to pick his options
/*
The loop will run what the user asks the program to run while at the same time also asking
what the programmer wants next
*/
while(*commandKey != 'X' || *commandKey != 'x') {
//int commandLength; //length of the command key
printf("Enter your menu selection: ");
gets(commandKey);
/*commandLength = strlen(commandKey);
fgets(commandKey, 100, stdin);
if(commandLength > 0 && commandKey[commandLength - 1] == '\n') {
commandKey[commandLength - 1] ='\0';
}*/
if(*commandKey == 'A' || *commandKey == 'a') {
int vowelCount;
vowelCount = vowel_count(userInput);
printf("There are %d vowels.\n\n", vowelCount);
}
if(*commandKey == 'B' || *commandKey == 'b') {
consonantCount = consonant_count(userInput);
printf("There are %d consonants.\n\n", consonantCount);
}
if(*commandKey == 'C' || *commandKey == 'c') {
/*
This condition simply converts the input string to all lowercase letters
*/
lowercase(userInput);
}
if(*commandKey == 'D' || *commandKey == 'd') {
/*
This condition simply converts the input string to all lowercase letters
*/
uppercase(userInput);
}
if(*commandKey == 'E' || *commandKey == 'e') {
/*
Prints the current string
if the string was converted in lowercase letters, the outcome would be all lowercase letters
if the string was converted in uppercase letters, the outcome would be all uppercase letters
*/
printf("%s\n\n", userInput);
}
if(*commandKey == 'F' || *commandKey == 'f') {
/*
When the user wants to test a new string, this is the condition for the user
to automatically ask of it
*/
printf("%s\n", PROMPT);
gets(newInput);
strcpy(userInput, newInput);
}
if(*commandKey == 'M' || *commandKey =='m') {
/*
In case the user forgets, this will serve as a reminder of the menu
*/
menu();
}
if(*commandKey == 'X' || *commandKey == 'x') {
printf("Goodbye!\n");
break;
}
}
}
//Function that displays the menu.
void menu() {
/*
These are the set of command keys given to the user
*/
printf("\n\n\n");
printf("PRESS:\n\n");
printf(" A - Count the number of vowels in the string.\n");
printf(" B - Count the number of consonants in the string.\n");
printf(" C - Convert the string to uppercase.\n");
printf(" D - Convert the string to lowecase.\n");
printf(" E - Display the current string.\n");
printf(" F - Enter another string.\n");
printf("\n");
printf(" M - Display this menu.\n");
printf(" X - Exit the program.\n");
printf("\n\n");
}
/*
Defining the function for the vowel counting
*/
int vowel_count(char *stringInput) {
if ( *stringInput == '\0')
return 0;
else
return vowel_count(stringInput + 1) + (*stringInput == 'a' || *stringInput == 'A')
+ (*stringInput == 'e' || *stringInput == 'E')
+ (*stringInput == 'i' || *stringInput == 'I')
+ (*stringInput == 'o' || *stringInput == 'O')
+ (*stringInput == 'u' || *stringInput == 'U');
}
/*
Defining the function for the vowel counting
*/
int consonant_count(char *stringInput) {
if (*stringInput == '\0')
return 0;
else
return consonant_count(stringInput + 1) + (*stringInput == 'b' || *stringInput == 'B')
+ (*stringInput == 'c' || *stringInput == 'C')
+ (*stringInput == 'd' || *stringInput == 'D')
+ (*stringInput == 'f' || *stringInput == 'F')
+ (*stringInput == 'g' || *stringInput == 'G')
+ (*stringInput == 'h' || *stringInput == 'H')
+ (*stringInput == 'j' || *stringInput == 'J')
+ (*stringInput == 'k' || *stringInput == 'K')
+ (*stringInput == 'l' || *stringInput == 'L')
+ (*stringInput == 'm' || *stringInput == 'M')
+ (*stringInput == 'n' || *stringInput == 'N')
+ (*stringInput == 'p' || *stringInput == 'P')
+ (*stringInput == 'q' || *stringInput == 'Q')
+ (*stringInput == 'r' || *stringInput == 'R')
+ (*stringInput == 's' || *stringInput == 'S')
+ (*stringInput == 't' || *stringInput == 'T')
+ (*stringInput == 'v' || *stringInput == 'V')
+ (*stringInput == 'w' || *stringInput == 'W')
+ (*stringInput == 'x' || *stringInput == 'X')
+ (*stringInput == 'y' || *stringInput == 'Y')
+ (*stringInput == 'z' || *stringInput == 'Z');
}
/*
Defining the function for the conversion of the string to all uppercase letters
*/
int uppercase(char *stringInput) {
while(*stringInput) {
*stringInput = toupper(*stringInput);
stringInput++;
}
}
/*
Defining the function for the conversion of the string to all uppercase letters
*/
int lowercase(char *stringInput) {
while(*stringInput) {
*stringInput = tolower(*stringInput);
stringInput++;
}
}
This loop will never stop:
while(*commandKey != 'X' || *commandKey != 'x')
A loop stops when its condition is false. For *commandKey != 'X' || *commandKey != 'x' to be false, it is logically equivalent for *commandKey == 'X' && *commandKey == 'x' to be true, which doesn't quite work. *commandKey can't be both 'X' and 'x'.
Instead, you want:
while(*commandKey != 'X' && *commandKey != 'x')
Which will stop when *commandKey is 'X' or 'x'.
Also, you never initialized commandKey, so you can't test it in the loop (using values of uninitialized variables is undefined behavior). And if you want to treat it as a string, you need to declare it such that it holds at least 2 characters, because the null character is needed:
char commandKey[2] = { 0 };
This will initialize commandKey to an empty string. Remember that gets() will null-terminate the string, so, even if your command is just one key, gets() will need at least 2 positions to fill - the character command and the null terminating byte. Alternatively, you can leave commandKey as is (provided that you initialize it), and use getchar() instead, which reads one single character.
I'm new to programming and I've decided to do some simple programming exercises.
The challenge is to remove all vowels from a user inputted string.
I've already wrote the code and I don't know why it isn't working.
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <ctype.h>
bool isVowel(char ch)
{
char charToBeTested = tolower(ch);
if(charToBeTested == 'a' || 'e' || 'i' || 'o' || 'u')
return true;
else
return false;
}
int main()
{
int i;
char formattedString[80];
printf("Enter a string: ");
scanf("%s", &formattedString);
for(i = 0; i < strlen(formattedString); i++)
{
if(isVowel(formattedString[i]) == true)
{
formattedString[i] = ' ';
}
}
printf("%s", formattedString);
return 0;
}
All it is supposed to do is check every character in the string and see if it's a vowel. If it's a vowel, replace the current character with a space. I will write the function to remove the spaces later.
All help is appreciated, sorry for being such a noob!
This code doesn't do what you think it does:
if (charToBeTested == 'a' || 'e' || 'i' || 'o' || 'u') {
...
}
C interprets this as
if ((charToBeTested == 'a') || 'e' || 'i' || 'o' || 'u') {
...
}
Here, the || operator is being applied directly to the character literals 'e', 'i', etc. Since C treats any nonzero value as "true," this statement always evaluates to true.
To fix this, try rewriting it like this:
if (charToBeTested == 'a' ||
charToBeTested == 'e' ||
charToBeTested == 'i' ||
charToBeTested == 'o' ||
charToBeTested == 'u') {
...
}
Alternatively, use a switch statement:
switch (charToBeTested) {
case 'a': case 'e': case 'i': case 'o': case 'u':
return true;
default:
return false;
}
Also, you might want to use tolower so that the testing is done case-insensitively.
Hope this helps!
This is incorrect:
if(charToBeTested == 'a' || 'e' || 'i' || 'o' || 'u')
correct is:
if(charToBeTested == 'a' || charToBeTested == 'e' || charToBeTested == 'i' || charToBeTested == 'o' || charToBeTested == 'u')
Or, you can create static table, like:
char vowels[0x100] = {
['a'] = 1,
['e'] = 1,
['i'] = 1,
['o'] = 1,
['u'] = 1,
};
And test by:
if(vowels[(unsigned char)charToBeTested])
You'll need to rewrite your isVowel function to something like:
bool isVowel(char ch)
{
char charToBeTested = tolower(ch);
if(charToBeTested == 'a') {
return true;
} else if(charToBeTested == 'e') {
return true;
} else if(charToBeTested == 'i') {
return true;
} else if(charToBeTested == 'o') {
return true;
} else if(charToBeTested == 'u') {
return true;
} else {
return false;
}
}
Alternatively, you can use a switch statement to do the same thing, like this:
bool isVowel(char ch)
{
char charToBeTested = tolower(ch);
switch(charToBeTested) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
return true;
default:
return false;
}
}
You need to test each alternative separately:
char c = tolower(ch);
if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u')
Your original code is:
if (charToBeTested == 'a' || 'e' || 'i' || 'o' || 'u')
The compiler evaluates that as:
if ((charToBeTested == 'a') || true)
because 'e' is not zero and any expression which is not zero is true.
If it optimizes really thoroughly, can deduce that the whole expression will always be true, regardless of the value of charToBeTested, and hence it can reduce the entire function to return true (without ever needing to call tolower(). If it was a static function, it could even eliminate the function call altogether. Whether any compiler would actually be that aggressive is open to debate.
Just to add to everyones answer; as they say, you need to fix your testing criteria.
Also, don't forget to check for the Uppercase version too:
if (charToBeTested == 'a' ||
charToBeTested == 'e' ||
charToBeTested == 'i' ||
charToBeTested == 'o' ||
charToBeTested == 'u' ||
charToBeTested == 'A' ||
charToBeTested == 'E' ||
charToBeTested == 'I' ||
charToBeTested == 'O' ||
charToBeTested == 'U') {
...
}