Basic Yes/No Program Abruptly Ends in C [duplicate] - c

This question already has answers here:
The program doesn't stop on scanf("%c", &ch) line, why? [duplicate]
(2 answers)
Closed 6 years ago.
I'm an absolute beginner to coding in C and I'm attempting to practice by writing a program where a user responds to Yes/No questions in a series, like if it were a game.
The problem that I'm having is that after the first question is answered, and the second pops up, the program doesn't give me (the user) a chance to respond to it; the program abruptly ends.
Obviously, there must be something simple that I'm missing here to go from one question to another without it terminating. I'd appreciate any advice.
Here's what I've made so far:
#include <stdio.h>
char answer, answertwo;
int main()
{
printf ("Are you laughing? (Y/N)\n" );
scanf ("%c", &answer);
if (answer == 'y' || answer == 'Y')
printf("\nGood\n");
else if (answer == 'n' || answer == 'N')
printf("\nBye\n");
printf("Do you want to read? (Y/N)\n ");
scanf ("%c, &answertwo");
if (answertwo == 'y' || answertwo == 'Y')
printf("\nGood\n");
else if (answertwo == 'n' || answertwo == 'N')
printf("\nBye\n");
return 0;
}

Two things:
You have a typo on the line scanf ("%c, &answertwo");, move the quote to the end of the first argument:
scanf ("%c", &answertwo);
The second call to scanf ends prematurely because it consumes the newline in stdin from the first call. Try replacing your format specifiers in scanf from "%c" to " %c" so that they will ignore whitespace before the actual character is input.

Related

scanf scans weird question marks in C [duplicate]

This question already has answers here:
What is the effect of trailing white space in a scanf() format string?
(4 answers)
Simple C scanf does not work? [duplicate]
(5 answers)
Closed 4 years ago.
I wrote this code for a school project and I have the following problem.
When I choose 1 at the first time, my program runs fine but as I choose w or r the second time, something goes wrong. None of the 2 ifs is running. I printed usr_ans2 to see the result of scanf and usr_ans2 variable is a weird question mark in a box and not a w or r character as I typed. Also I tried scanf(" %c", usr_ans2) . The question marks do not appear but the if commands are still not running.
int main(){
int usr_ans1;
char usr_ans2;
while(1){
printf("\nSelect action: (1-3)\n");
scanf("%d", &usr_ans1);
if(usr_ans1 == 1){
printf("Select to write or read from a file the text: (w/r) ");
usr_ans2 = scanf("%c", &usr_ans2);
if(usr_ans2 == 'w')
printf("You selected to write");
else if(usr_ans2 == 'r')
printf("You selected to read");
}
else if(usr_ans1 == 2){
printf("Example1");
}
else if(usr_ans1 == 3){
printf("Example2");
}
return 0;
}
scanf() in usr_ans2 = scanf("%c", &usr_ans2); will return 1 (the numbers of successfully converted specifiers) or EOF (some negative value like -1 when end-of-file or error occurs). if(usr_ans2 == 'w') will never be true.
Try
// usr_ans2 = scanf("%c", &usr_ans2);
scanf(" %c", &usr_ans2); // add the space too to skip leading white-space

In C - scanf() in a for loop is causing printf() to run multiple times

I'm completing an assignment and after completing it, I have 1 bug, and 1 bug fix I made that I don't fully understand. Currently, as long as the user does what is asked, everything works fine. But I know that doesn't happen often, so I'd love to know how to stop these issues.
Would love any advice - I am a complete beginner with C.
I found many different pieces of advice here: C: Multiple scanf's, when I enter in a value for one scanf it skips the second scanf
I added a space to my scanf() statements which solved some of the bugs - and I understand that \n is added onto the end of the entered strings / chars, I'm just not sure how to check for it / handle it, and I tried using getchar() in place of the scanf() but I still get double print / loop problems.
Bug Issue
When the user is running through the game loop, if they enter more than 1 character (for example: 'oo', when prompted with the scanf() to enter 'y' or 'n') my printf statements run 1x per character entered, and connect to each other:
Example would be:
Welcome to Two doors.
Would you like to play? (y/n):Welcome to Two doors.
Would you like to play? (y/n):
This issue also shows up if the user enters 'y' to play the game but then enters a character other than 1,2 or 3 in the second section.
How can I limit the length of their response? Or is the best way to monitor the length of the play and choice variables prior to entering the if statements? Maybe checking to see if they are longer than 1 character and if so, only taking the first character?
Second issue - bug fix that I don't understand
In the scanf() functions I ran into a very similar problem to what I described above, but it happened when the user entered any character. The solution I found was to add a space before the character ->
scanf(" %c", &play);
vs
scanf("%c", &play);
Is this issue only a problem when using loops? Since I never found these bugs prior to looping back through the code.
Updated Code with 'while (getchar() != '\n');' suggestion from Sourav Ghosh
#include <stdio.h>
int main(void) {
char play;
int choice;
char answer[] = "No matter which one you choose the guards both tell you which door leads to death, and therefore you can pick the other door.\n";
int gameLoop = 1;
int timesPlayed = 0;
while (gameLoop == 1){
if (timesPlayed == 0) {
printf("Welcome to Two doors.\n");
printf("Would you like to play? (y/n):");
} else {
printf("Would you like to play again? (y/n):");
}
scanf(" %c", &play);
while (getchar() != '\n');
if (play == 'y') {
// == instead of =
printf("\nYou are a prisoner in a room with 2 doors and 2 guards.\n");
printf("One of the doors will guide you to freedom and behind the other is a hangman --you don't know which is which.\n");
printf("One of the guards always tells the truth and the other always lies. You don't know which one is the truth-teller or the liar either.\n");
printf("You have to choose and open one of these doors, but you can only ask a single question to one of the guards.\n");
printf("What do you ask so you can pick the door to freedom?\n\n");
printf("\t1.Ask the truth-guard to point to the door of doom.\n");
printf("\t2.Ask the liar-guard to point to the door of doom.\n");
printf("\t3.Doesn't matter which one you pick.\n");
scanf(" %d", &choice);
while (getchar() != '\n');
switch (choice) {
case 1:
printf("%s", answer);
timesPlayed++;
break;
case 2:
printf("%s", answer);
timesPlayed++;
break;
case 3:
printf("%s", answer);
timesPlayed++;
break;
default:
printf("The Troll Smasher comes out from the shadows and squeezes the stupid out of you until you pop. GAME OVER!\n");
break;
}
} else if(play == 'n') {
printf("Sorry to hear that, we at Two Doors hope you have a super duper day!\n");
gameLoop = 0;
break;
} else {
printf("That is not a valid input, please try again by entering either 'y' to start the game or 'n' to quit the game.\n");
}
}
return 0;
}
The problem with %c format specifier is that, it will read only one byte from the input buffer and if the input buffer has more in store and the call in encountered next time, it will not ask for user input, it will simply read the next byte from the available input stream.
So, to answer
How can I limit the length of their response?
well, there's no straightway approach that you can stop the user from entering only X characters/ digits, instead, swipe off the excess, (if any) and for the next call, start with an empty buffer is an easy approach.
So, the quick way out of this would be, to clean off the standard input of remaining inputs. You can do something like
int retval = scanf(" %c", &play);
//some code
while (getchar() != '\n'); //eat up the input buffer
//next call to scanf(), input buffer is empty now....
to stop scanf() from reading already existing unwanted inputs and force it to ask the input from user.
Also, don't forget to check the return value of scanf() to ensure the success of the call.
For the first issue the problem is caused because the execution of the program enters the loop again for example if the user types oo that means that after reading with scanf it is going all the way to the last else.
Inside that else none of the variables is modified so when it reenters the loop gameLoop is still 1 and timesPlayed is still 0 so it will print the statements in the first if, then scanf will read the second o and repeat the process. The problem is that scanf reads one character at the time.
Actually for entering one character you can use getchar() but in any case after char input you should clean standard input stream. Consider the following example, that forces the user to the correct input:
char name[11];
char answer = 0;
printf("Would you like to play again? (y/n): ");
while ((answer = getchar()) != 'y' && answer != 'n')
{
printf("You should answer 'y' or 'n'\n");
// clean the buffer from mess
while (getchar() != '\n');
}
// clean the buffer from mess
while (getchar() != '\n');
// next input
printf("Enter your name: ");
scanf("%10s", name);
// clean the buffer from mess
while (getchar() != '\n');
UPDATE:
Just for clarification, the code
while ((answer = getchar()) != 'y' && answer != 'n')
{
printf("You should answer 'y' or 'n'\n");
// clean the buffer from mess
while (getchar() != '\n');
}
can be be easier to understand while rewritten as
char name[11];
char answer = 0;
printf("Would you like to play again? (y/n): ");
while (1) // infinit loop
{
answer = getchar();
// clean the buffer from mess (immideatly after reading)
while (getchar() != '\n');
if (answer == 'y' || answer == 'n') // check the input
break; // stop the loop if condition is true
// or ask again
printf("You should answer 'y' or 'n'\n");
}
// next input
printf("Enter your name: ");
scanf("%10s", name);
// clean the buffer from mess
while (getchar() != '\n');
in my first example I just optimize the code combining reading and checking the data in parentheses after while: (answer = getchar()) != 'y' is like two actions - answer = getchar() and then answer != 'y'
In the last snippet condition answer != 'y' && answer != 'n' was intentionally replaced with answer == 'y' || answer == 'n' to show difference between "do while data is incorrect" and "stop when correct data get"

Beginning C and I have a bug that is killing me [duplicate]

This question already has answers here:
Problems with C scanf("%c") function to read characters one by one
(4 answers)
Closed 6 years ago.
I am writing some code and I have a prompt in the program driven by a while loop where you make a choice. However, it prints the prompt twice every time it goes through the loop and I just can't figure it out.
while (choice != 'x');
{
printf("\nChoice (a)dd (v)iew e(X)it [ ]\b\b");
scanf("%c",&choice);
if (choice == 'a') add_record();
if (choice == 'v') view_record();
}
The printf line is the one that prints twice. Thanks in advance for any help.
When you enter a character (i.e. type 'a' and press 'Enter'), the newline character ('\n') is also being read in from stdin. You can add a leading space to the format specifier to avoid this:
scanf(" %c", &choice);
The space indicates to scanf to ignore whitespace characters (such as '\n').
There are few things to notice in the question posted.
The outer while loop behavior depends on the variables initialization at first then the values being entered subsequently.
It then manipulates into print the prompt to enter choice, repeatedly (not just twice) depending on how many characters entered as input before 'enter' key is pressed.
The char i/o driver buffers the input entered and each of the characters entered is read by scarf() one at a time in this case, from the buffer. So it is needed to rewrite the code to work as following (expected from my understanding)
char choice = '!', ws = ' ';
int attempts = 0;
while (choice != 'x')
{
printf("\nAttempt:%d Choice (a)dd (v)iew e(X)it [ ]\b\b", ++attempts);
// Eat up the '\n', if one exist and Wait for valid input
while ((scanf("%c", &choice) > 0) && (choice == '\n'));
// Eat up all white space and other chars entered so far, except the last '\n'
while ((scanf("%c", &ws) > 0) && (ws != '\n'));
if (choice == 'a') add_record();
if (choice == 'v') view_record();
}

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');
}

do-while is not working as expected [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I am new to c and writing a program in c on linked list. Its a simple program.
I am using it to enter number to list till user wants.
The code is as :
do {
system("clear");
printf ("\nEnter a no to add to list : ");
scanf ("%d",&num);
append (&p,num);
display (p);
printf ("\n\nWhant to add more...(Y/N) : ");
choice = getchar();
} while (choice == 'y' || choice == 'Y');
When user enters choice, program exits...
I am using gcc compiler on linux [ubuntu] to compile and run it.
Your scanf reads a number and stops reading from stdin, but when you enter a number you send the number plus the \n character. That is what getchar() reads. It is not a y or a Y, so the loop finishes.
Change your getchar() line with this one:
scanf(" %c", &choice);
...and it should work.
Put: getchar();
before
choice = getchar();
To consume the \n character that is left in stdin after scanf().
The code then results to:
do {
system("clear");
printf ("\nEnter a no to add to list : ");
scanf ("%d",&num);
append (&p,num);
display (p);
printf ("\n\nWhant to add more...(Y/N) : ");
getchar(); //needed to consume the \n character
choice = getchar();
}while (choice == 'y' || choice == 'Y');
getchar() returns the next character from the standard input (stdin)
When you press enter after the scanf() statement, a \n character got accumulated in the input buffer. Thus the value of choice set to \n automatically and the loop condition became false.
You can use scanf() instead of getchar() to read formatted data from stdin eventually to hold the value of choice.
do {
system("clear");
printf ("\nEnter a no to add to list : ");
scanf ("%d",&num);
append (&p,num);
display (p);
printf ("\n\nWhant to add more...(Y/N) : ");
scanf(" %c", &choice);
} while (choice == 'y' || choice == 'Y');

Resources