The code "should" work, but the program stops working - c

I'm a beginner with a few hours of expirience and I'm trying to make a really simple program to get familiar withe IF command. I came up with this code:
#include<stdio.h>
int main()
{
char ans;
char n;
char y;
printf("Do you want to exit?\n");
scanf("%c\n",ans);
if (ans == y)
{
printf("As you wish!\n");
return 0;
}
else (ans == n);
{
printf("You'll exit anyways!\n");
return 0;
}
}
I think it should work, but after I type something the program stops workig! Thanks in advance!

The
if (ans == y)
should read
if (ans == 'y')
The former compares ans to the value of the uninitialized variable y, whereas the latter checks whether ans contains the character 'y'.
The same goes for 'n'.
The y and n variables are unnecessary and can be removed.
Also, the following line is incorrect:
else (ans == n);
It should read
else if (ans == 'n')
(I've added the if and have removed the semicolon.)
Finally, the scanf() should read:
scanf("%c",&ans);

else (ans == n);
This doesn't give expected results. Remove the ; and the condition.
else may only take a body of code. It does not handle conditions.
If you want conditions, use else if:
else if (ans == 'n')
More errors:
if (ans == y)
y in here refers to the variable, which is declared but has no value. Surely you want to refer to the character 'y':
if (ans == 'y')
Also, scanf expects a pointer, so instead of ans, use &ans.
It needs to write to the memory address of the value. It doesn't care about the value.
You'll learn about pointers eventually. (Assuming you haven't gone over them in your few hours of experience)

There are three main errors.
You should pass pointers to the scanf function, so you have to add an ampersand before ans (&ans).
There is a trailing ; at the end of the else statement.
y refers to a variable (which does not exist), whereas you want to compare ans against the character 'y'.

Related

How do characters store values when being compared to each other in an if else?

I'm creating a loop that basically has a (y/n) yes, no answer and I wanted to use an if else inside of a do while loop. When using the input == Y it seems to not accept it, so I'm wondering that's even possible in C? Or if I'm approaching in the wrong way.
I tried just a simple if input == Y but that didn't work, then I tried a strcmp and that didn't seem to work either. I'm at the strcmp part because I think I might be close to the answer with that but I'm not entirely sure if I'm understanding what's going on with the char values.
printf("Would you like to print another invoice? Y=yes, N=No\n");
do {
scanf("%s", &newInvoice);
if(strcmp(newInvoice, Y)!= 0) {
main();
}
else if(strcmp(newInvoice, N)!= 0) {
printf("Goodbye!\n");
}
else {
printf("Invalid Entry (it has to be y or n):\n");
}
} while(strcmp(newInvoice, N)!= 0);
When I had just input == Y it wanted me to initialize Ym and N so that didn't seem to be the answer. I would like the loop to repeat the question and input until they say yes or no; if they enter something like G or whatever other character it needs to loop again.
consider the following (changed abelenky's code a little). The below makes sure the lower case letters get accepted, but it's probably a little clunky, and may be represented a little more elegant.
int main()
{
char newInvoice, buffer;
do
{
newInvoice = getchar();
bufferClean(&buffer); //see underneath the code for the explanation.
if (newInvoice == 'Y' || newInvoice == 'y')
{
printf("you've chosen YES, continue ......\n");
break; // breaks the loop and continues with the code.
}
else if (newInvoice == 'N' || newInvoice == 'n')
{
printf("you've chosen NO, Goodbye!\n");
return 1; //main returns 1 and ends the program
}
else
{
printf("Invalid Entry (it has to be y or n):\n");
}
} while(1);
printf("exited the loop\n");
return 0;
}
Also, asking for users' input is a little tricky. I suggest clearing the buffer after using it, as it passes on the newline char and may skip any further input prompt.
I have created a little function to do so:
void bufferClean(char *buff)
{
while ((*buff = getchar()) != '\n' && *buff != EOF);
}
Just declare a char buffer in main() with no value, and pass it on to the function every time you want to clear the buffer (I do every time after asking for users' input). I'm a novice, and if I'm making any mistakes please point them out!

Warning: comparison b/w pointer and integer in C.

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.

Do-While loop in C - error at printing

I am making a little program that takes as input the answer to the question "Are you an adult?" as a character like that:
bool adult() {
char answer;
do {
printf("Are you an adult? [y/n]\n");
answer = getchar();
} while (!(answer == 'y' || answer == 'n'));
return (answer == 'y');
}
My aim was that the question should repeat itself if the answer is neither y or n. But this seems to have a bug:
When I answer something else (neither y or n), the question gets printed twice:
Are you an adult?
u
Are you an adult?
Are you an adult?
...
Why is this happening?
Also, I've tried the same method with scanf instead of getchar but there is the same bug. For this kind of program, should I use scanf or getchar and why?
Thanks!
Actually the extra '\n' in the answer with (yes) y or (no) n gets counted and it's printed twice. You just remember to get that dummy '\n'. Use another extra getchar(). The dummy getchar() is a solution to this problem.
bool adult() {
char answer;
do {
printf("Are you an adult? [y/n]\n");
answer = getchar();
getchar(); //~~~~~~~~~~~~~~~~~~~~> this is what gets the extra '\n'
} while (!(answer == 'y' || answer == 'n'));
return (answer == 'y');
}
You can check my other answer here.You will get a clear idea.
the input buffer in getchar() and scanf
EDIT: As pointed out by Random832 in case of yes\n the ye is consumed but not the s\n. so a better solution is to store the first character and consume every other character until \n using a do..while or while loop. Then check the first character. Or you can store the whole string as per your need and use the first character to get the answer.
EDIT 2: flushing is not a solution to this problem. Previously I mentioned it. iharob pointed out to me that. You can check this two answers to get a clear idea.
Flushing buffers in C
How to clear input buffer in C?
To make the code robuts, i.e. for it to work with any input, you might need to read all the characters that you are not going to consider as valid, including the '\n' that is sent when you press enter and flush the input buffer, which you can't do by using fflush(), because it's only defined for output buffers, you should also consider the case of an empty line, i.e. when the user presses Enter immediately, the following code does all what I describe
#include <stdio.h>
#include <stdbool.h>
bool
adult()
{
char answer;
do {
int chr;
printf("Are you an adult? [y/n] ");
answer = getchar();
if (answer == '\n')
continue;
while (((chr = getchar()) != EOF) && (chr != '\n'));
} while (!(answer == 'y' || answer == 'n'));
return (answer == 'y');
}

How Does Char Variable Work in C

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

Comparing user-inputted characters in C

The following code snippets are from a C program.
The user enters Y or N.
char *answer = '\0';
scanf (" %c", answer);
if (*answer == ('Y' || 'y'))
// do work
I can't figure out why this if statement doesn't evaluate to true.
I checked for the y or n input with a printf and it is there, so I know I'm getting the user input. Also when I replace the the condition of the if statement with 1 (making it true), it evaluates properly.
I see two problems:
The pointer answer is a null pointer and you are trying to dereference it in scanf, this leads to undefined behavior.
You don't need a char pointer here. You can just use a char variable as:
char answer;
scanf(" %c",&answer);
Next to see if the read character is 'y' or 'Y' you should do:
if( answer == 'y' || answer == 'Y') {
// user entered y or Y.
}
If you really need to use a char pointer you can do something like:
char var;
char *answer = &var; // make answer point to char variable var.
scanf (" %c", answer);
if( *answer == 'y' || *answer == 'Y') {
answer shouldn't be a pointer, the intent is obviously to hold a character. scanf takes the address of this character, so it should be called as
char answer;
scanf(" %c", &answer);
Next, your "or" statement is formed incorrectly.
if (answer == 'Y' || answer == 'y')
What you wrote originally asks to compare answer with the result of 'Y' || 'y', which I'm guessing isn't quite what you wanted to do.
For a start, your answer variable should be of type char, not char*.
As for the if statement:
if (answer == ('Y' || 'y'))
This is first evaluating 'Y' || 'y' which, in Boolean logic (and for ASCII) is true since both of them are "true" (non-zero). In other words, you'd only get the if statement to fire if you'd somehow entered CTRLA (again, for ASCII, and where a true values equates to 1)*a.
You could use the more correct:
if ((answer == 'Y') || (answer == 'y'))
but you really should be using:
if (toupper(answer) == 'Y')
since that's the more portable way to achieve the same end.
*a You may be wondering why I'm putting in all sorts of conditionals for my statements. While the vast majority of C implementations use ASCII and certain known values, it's not necessarily mandated by the ISO standards. I know for a fact that at least one compiler still uses EBCDIC so I don't like making unwarranted assumptions.
Because comparison doesn't work that way. 'Y' || 'y' is a logical-or operator; it returns 1 (true) if either of its arguments is true. Since 'Y' and 'y' are both true, you're comparing *answer with 1.
What you want is if(*answer == 'Y' || *answer == 'y') or perhaps:
switch (*answer) {
case 'Y':
case 'y':
/* Code for Y */
break;
default:
/* Code for anything else */
}

Resources