int main()
{
char name[10], food[10], color[10], ans[10];
int height, year, age, date;
/* Ask for user inputs and do stuff here */
/* ------------------------------------- */
printf("Would you like me to repeat this?\n");
scanf("%c", ans);
/* its giving me a warning for the if condition on the line */
/* below saying warning: comparison b/w pointer and integer. */
if (ans == 'y')
printf("ok I will\n");
else
printf("fine.\n");
return 0;
}
At the end of the program, I wrote an IF statement where if user types "y" then it'll say "ok I will" ELSE say "fine" -nothing fancy.
But when I run it, the program would ask me "Would you like me to repeat this?" and even though I type "y" the program will output "fine" instead of "ok I will"... please help.
The variable ans is an array, and can decay to a pointer to the first element. You compare it to a character.
You should change to e.g. ans[0] == 'y'.
Or even better, since you only read a single character, why us an array at all? Just declare ans as a single character, and use the address-of operator in the scanf call:
char ans;
scanf(" %c", &ans);
if (tolower(ans) == 'y') ...
You're comparing ans which is regarded as pointer ,to 'y' which is regarded as integer. change char ans[10] to char ans.
Related
This question already has answers here:
Program not recognizing character inputs in if-else statements
(5 answers)
Closed 1 year ago.
I'm writing a C program that asks the user for a variety of inputs, one is a Yes or No question. If you put Y, or y, the If statement is supposed to execute. However, no matter what you input, it goes through with the If statement.
double phonePrice;
double phoneTax;
double phoneTotal;
double phoneApplePrice;
double phoneSubtotal;
double temp;
int yearsAppleCare;
char userAnswer;
//prompting for price
printf("Enter the price of the phone> ");
scanf("%f", &phonePrice);
fflush(stdin);
//prompting for iphone
printf("Is the phone an iPhone (Y/N) ?> ");
scanf("%c", &userAnswer);
fflush(stdin);
//nested if statements asking for apple care amount
if(userAnswer=="Y"||"y")
{
printf("Enter the number of years of AppleCare> ");
scanf("%d", &yearsAppleCare);
if(yearsAppleCare<=0)
{
printf("You must choose at least 1 year of AppleCare");
return 0;
}
}
Any help with this would be appreciated.
For starters this call
fflush(stdin);
has undefined behavior. Remove it.
Instead of this call
scanf("%c", &userAnswer);
use
scanf(" %c", &userAnswer);
^^^^
to skip white spaces in the input buffer as for example the new line character '\n'.
Also for double variables use the conversion specifier %lf. For example
scanf("%lf", &phonePrice);
The condition in the if statement
if(userAnswer=="Y"||"y")
is equivalent to
if( ( userAnswer=="Y" ) || ( "y" ) )
As the string literal "y" that is implicitly converted to a pointer to its first element is not equal to a null pointer then the condition always evaluates to logical true.
You need to write
if( userAnswer == 'Y' || userAnswer == 'y' )
using integer character constants 'Y' and 'y' instead of the string literals.
Error is here:
//nested if statements asking for apple care amount
if(userAnswer=="Y"||"y")
{
Should be:
//nested if statements asking for apple care amount
if(userAnswer == "Y" || userAnswer == "y")
{
Wait! No!
Should be:
//nested if statements asking for apple care amount
if( strcmp(userAnswer, "Y") == 0 || strcmp(userAnswer, "y") == 0)
{
Why?
What does == mean?
In C language, == means the two objects are equal. In the case of strings, the objects are char*, I.e. pointers to char. These will be equal if and only if the memory address is the same. This will not be true in this case.
Why? Because one string is compiled into the program and initialised as the program starts, and the other is provided by the user into temporary memory. These will be at different addresses so the pointers will not be the same.
What you probably want is to compare the contents of the memory locations pointed to by the two pointers.
For that purpose the strcmp function is provided. This function returns zero if the strings are the same. You may also want to consider stricmp.
I am pretty sure this was asked before but I could not find any answers, so here I go. This is a simple line of code and I cannot get it to exit the while loop. If I change the || to && the loop just exit no matter what I press. Thank you for the answers.
#include <stdio.h>
int main()
{
int answer;
printf("Are you sure you want to exit the program? Type in 1 for yes and 2 for no.\n");
scanf("%d", answer);
//This is to check that the user inputs the right number if not error message is displayed
while(answer <1 || answer > 2)
{
printf("Please type in 1 to exit the program and yes and 0 to keep playing. \n");
scanf("%d", answer);
flushall();
}
return 0;
}
If You want to exit on 1, then You just need to check if input is equal to it, that is why I want to scan for more answers when it is not equal to 1. If it is then it will omit while loop and go directly to return 0.
Also I changed the way of usage of scanf - when you declare a variable (in Your case answer), system gives it an address in the memory. Then you use scanf to take an input from the user, and after you take the input, you write it on the address of that variable so that when you refer to it later, the system goes to the address and retrieve the value.
int main()
{
int answer;
printf("Are you sure you want to exit the program? Type in 1 for yes and 2 for no.\n");
scanf("%d", &answer);
//This is to check that the user inputs the right number if not error message is displayed
while(answer != 1)
{
printf("Please type in 1 to exit the program and yes and 0 to keep playing. \n");
scanf("%d", &answer);
}
return 0;
}
This is one the frequent cases of misunderstanding/forgetting how scanf works.
int scanf ( const char * format, ... );
reads formatted data from stdin.
It reads data from stdin and stores data according to the parameter format into the locations pointed by the additional arguments.
The additional arguments should point to already allocated objects of the type specified by their corresponding format specifier within the format string.
It means that arguments should be pointers.
In your case:
int answer;
scanf("%d", answer);
answer is not a pointer but the variable (object) of type int.
To satisfy the scanf you have to use a pointer to the answer.
You can do it using the unary or monadic operator & which gives the address of a variable.
scanf("%d", &answer);
or you could use a pointer pointing to the answer:
int answer;
int answer_ptr = & answer;
scanf("%d", answer_ptr);
which is also correct but typically there is no need to go for this construction.
Secondly the line:
while(answer <1 || answer > 2)
You may want to modify it to
while (answer != 1 && answer != 2)
if you are interested in breaking the while loop when answer is being equal to 1 or 2.
I'm following a tutorial on youtube and was doing a dice generator.
It basically print out 3 dice result and sum out the dice result.
After which, the user will look at the sum, and based on the sum, the user going to guess whether the next roll is going to be higher,lower, or the same.
Below is my code, suppose, when I typed 'yes', it should be doing the code inside the if statement. However, it went straight to the else statement. Can someone please tell me what's wrong?
int answer;
int guess;
int diceRoll4 = 0;
printf("Would you like to guess your next dice? Y/N \n");
scanf(" %c", &answer);
if (answer == 'yes' ){
printf("What is your guess?\n");
printf("please key in your number \n");
scanf(" %d", &guess);
if (guess > diceRoll4 ){
printf(" You got it wrong, too high!");
}
else if (guess < diceRoll4){
printf(" You got it wrong, too low!");
}
else {
printf("You got it right");
}
}
else{
printf("Thanks for playing");
}
First of all, answer should be an array of chars in order to hold a string. Change
int answer;
to
char answer[10]; //Or any other reasonable size
Secondly, since you want to scan a string and not a character, change
scanf(" %c", &answer);
to
scanf("%9s", answer);
The 9 will scan a maximum of 9 characters (+1 for the NUL-terminator at the end), thus preventing buffer overflows.
I've removed & as %s expects a char* while &answer will give a char(*)[10]. Name of an array gets converted into a pointer to its first element char*, exactly what %s expects. The above scanf is thus equivalent to
scanf("%9s", &answer[0]);
Thirdly, comparing two strings using == compares pointers and not the actual content in them. Use strcmp from string.h instead. It returns 0 when both its arguments hold the same content. Change
if (answer == 'yes' ){
to
if (strcmp(answer, "yes") == 0){
Double quotes are used to denote a NUL-terminated string(char*), which is exactly what strcmp expects, while single quotes, as in your code, is a multi-character literal whose value is implementation-defined.
'yes' is a multi-byte character whose behaviour is implementation-defined.
What you probably want is to read and compare a single char:
if (answer == 'y' ){
or read a whole string and compare:
char answer[128];
scanf("%s", answer);
if ( strcmp(answer,"yes") == 0 ){
...
}
Notice that I changed the type of answer and used %s to read a string.
If you do not want to read in a string, but only a single char where the user can answer either Y or N, you should change int answer; to char answer;. You can then go on using your original scanf()-call. You will still need to change
if (answer == 'yes')
to
if (answer == 'Y')
If you want the user to either type in y or Y you could user toupper() from ctype.h and change your if-condition to if (toupper(answer) == 'Y').
To test the equality you have to use strcmp. If the returning value is 0 it means that they are equal.
if (strcmp(answer, "yes") == 0) {
// ...
} else {
// ...
}
Notes:
Using just answer == 'yes' it test the equality of pointers not value. This is the reason why enters only in else.
Because answer is int you have to change to an array
char answer[15]
As #Sathya mentioned you are reading just a char %c for reading a string you have to use %s
scanf("%s", answer);
Instead of 'yes' which is multi-character character constant change to "yes" that is an array of char with \0 at the end, more informations here.
this line:
if (answer == 'yes' ){
has several problems.
1) the definition of 'answer' is 'int' but the scanf is inputting a single character
2) answer could be compared with 'y' or 'n' but not to a array of char.
3) since the scanf only input a single char
and you/the user input 'yes',
only the first character was consumed,
so the 'es' are still in the input buffer
4) note the the single character could be anything, except white space.
the leading space in the format string would consume any white space.
so the user could input say 'y' or 'Y'
these are different characters
however, using the toupper() macro from ctypes.h
would mean only a 'Y' would need to be compared
5) if you decide to read a string,
then 'answer' needs to be a character array,
say: char answer[10];
and the scanf needs to have a max length modifier
on the associated "%s" input/conversion parameter
so as to avoid the user overflowing the input buffer
and the comparison would be via the strcmp() function
6) always check the returned value (not the parameter value)
from scanf to assure the operation was successful
7) diceRoll4 and guess can never be a negative number
so the variable definitions should be unsigned
and the associated scanf() for guess should use
something like "%u"
8) on the printf() format strings, always end them with '\n'
so the sting will be immediately displayed to the user,
otherwise, they will only be displayed
when a input statement is executed or the program exits
The code is,
#include <stdio.h>
#include <string.h>
main()
{
int a, b, s;
char ch;
LOOP:
printf("enter digits \t");
scanf("%d %d", &a, &b);
s = a + b;
printf("\n answer is %d", s);
printf("\n add another no.? (yes/no) : \t");
scanf("%c", &ch);
if (ch == "yes")
goto LOOP;
if (ch == "no")
printf("\n Okay bye !!! ");
exit(0);
return 0;
}
Can someone tell why this ain't working? When it asks:
Add another no.?
I cant type anything, I type but nothing gets print.
Thx in advanced.
First if you want to store "yes" you will need a char array, not a single char.
Then you can not compare char arrays with string literals like this: ch == "yes", you have to use "string compare", strcmp or strncmp.
"yes" is a char*(or pointer to char), which can't be compared using ==. In this case you need to use the library function strncmp() which compares two strings. Also a char is a data type which typically holds one byte of information in which case a single char cannot contain the 3 character string "yes". In your use of scanf to populate &ch, ch will end up only containing the first char of the input due to char's size.
Your code says to input 1 for yes and 0 for no, whereas you are checking for ch=="yes" and ch =="no".
You can initialize an integer, say, int choice; and then:
printf("\n add another no.? 1 for yes / 0 for no : \t");
scanf("%i", &choice);
if (choice == 1)
goto LOOP;
if (choice == 0){
printf("\n Okay bye !!! ");
exit(0);
}
NOTE that the exit(0) should be inside the if() statement, i.e. between {curly brackets}. When we don't use {curly brackets} with if() statement, only the first piece of code after the if(), that is printf(); in this case, is taken with the if().
Secondly, if you want to use yes and no instead of 1 and 0, then in that case you cant compare a string with == operator. To compare two string you use strcmp function, which returns 0 if the strings are same and some positive or negative value if not same. (that's why we have to use ! operator with strcmp, so that in case strings are same, and the strcmp return 0, !0 becomes 1 which means true and if statement is executed.)
We initialize ch, a string as char ch[5]; and then:
printf("\n add another no.? yes for yes / no for no : \t");
scanf("%s", ch);
if (!strcmp(ch,"yes"))
goto LOOP;
if (!strcmp(ch,"no")){
printf("\n Okay bye !!! ");
exit(0);
}
What I am trying to accomplish is prompting the user with the question of do they want to run the program again. They either type y or n. If y, it reruns the program. If no, it stops the program. Anything other than those two will prompt an error and ask the question again. I'm used to C# where strings are not complicated, but in C, I guess there technically isn't strings, so we have to use either char arrays or char pointers. I've tried both, none that work that way I want, but I'm probably the problem. This is what I have.
char answer[1] = "a";
while (strcmp(answer, "y") != 0 || strcmp(answer, "n") != 0)
{
printf ("\n\nWould you like to run the program again? Type y or n. Then, hit Enter.");
scanf ("%c", answer);
if (strcmp(answer, "y") == 0)
{
main();
}
else if (strcmp(answer, "n") == 0)
{
continue;
}
else
{
printf ("\nERROR: Invalid input was provided. Your answer must be either y or n. Hit Enter to continue.");
F = getchar();
while ((getchar()) != F && EOF != '\n');
}
}
I have other while loops similar to this that work as expected, but use a float. So I'm assuming the problem is me using char here. What happens right now is that it doesn't even prompt the user for the question. It just asks the question and shows the error right afterwards. I'm sure there are other things wrong with this code, but since I can't get the prompt to work, I cannot test the rest of it yet.
I suggest using a light weight getchar() instead of the heavy scanf.
#include <stdio.h>
int c; /* Note getchar returns int because it must handle EOF as well. */
for (;;) {
printf ("Enter y or n\n");
c = getchar();
switch (c) {
case 'y': ...
break;
case 'n': ...
break:
case EOF:
exit(0);
}
}
"a" is a string literal == char id[2]={'a','\0'} //Strings are
char arrays terminated by zero, in C
'a' is a char literal
strcmp is just "compare each char in two strings, until you hit '\0'"
scanf ("%c", ___); expect an address to write to as the second
argument. Functions in C cannot modify their arguments (they don't
have access to them--they get their own local copy) unless they have
a memory address. You need to put &answer in there.
Jens has already basically answered the question, you most likely want to use getchar so that you can detect EOF easily. Unlike scanf("%c",...), getchar will not skip spaces, and I believe both versions will leave you with the unprocessed rest of the input line (a newline character ('\n') at least) after each getchar. You might want to something like
int dump;
while((dump=getchar())!='\n' && dump!=EOF) {};
So that you discard the rest of the line once you've read your first character of it.
Otherwise, the next getchar will get the next unprocessed character of the same line. ('\n' if the line was a single letter).
Here is one way to do it. It is by no means the only way to do it, but I think it accomplishes what you want. You should not call the main function recursively.
#include <stdio.h>
#include <stdlib.h>
void run_program()
{
printf("program was run.");
}
int main() {
char answer[2] = "y\0";
int dump;
do {
if (answer[0] == 'y')
{
run_program(); /* Not main, don't call main recursively. */
}
printf ("\n\nWould you like to run the program again? Type y or n. Then, hit Enter.\n");
scanf ("%1s", answer);
/* Dump all other characters on the input buffer to
prevent continuous reading old characters if a user
types more than one, as suggested by ThorX89. */
while((dump=getchar())!='\n' && dump!=EOF);
if (answer[0] != 'n' && answer[0] != 'y')
{
printf ("Please enter either y or n\n");
}
} while (answer[0] != 'n');
return 0;
}
Using %s instead of %c, reads in the new line so that the new line character is not in the stdin buffer which would become answer then next time scanf was called.
The run_program function is just a function where you would put your program's logic. You can call it whatever you want. I did this to separate out the menu logic from the logic of the actual program.
Well, you are comparing two strings instead of characters.
If you want to compare two character you have to follow this syntax:
char c;
scanf("%c",&c);
if(c == 'y')
//do something
else
//do nothing