do-while is not working as expected [closed] - c

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

Related

Why use getchar in specific line? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
Why the following code is getting terminated after one round if the getchar() in the 5th line is not used?
char s;
while(1){
printf("Enter two integers: ");
scanf("%d%d",&a,&b);
getchar();
c = a + b;
printf("Addition of %d & %d is %d\n",a,b,c);
printf("Add more numbers(yes/no): ");
scanf("%c",&s);
if(s == 'y')
continue;
else
break;
}
And why using string is not working in the following code? I have included the <string.h> file.
char s[10];
while(1){
printf("Enter two integers: ");
scanf("%d%d",&a,&b);
getchar();
c = a + b;
printf("Addition of %d & %d is %d\n",a,b,c);
printf("Add more numbers(yes/no): ");
scanf("%s",s);
if(s == "yes")
continue;
else
break;
}
When you enter the input for the first scanf("%d%d",&a,&b) then you probably ended that with the Enter key.
That Enter key is added as a newline into the input buffer that scanf reads from.
If you don't have the getchar() call then that newline is what the next scanf("%c",&s) will read.
One solution is, as you've noted, to use getchar() to read and throw away the newline. Another solution is to ask scanf to do the same:
scanf(" %c",&s);
// ^
// Note the space here!
The leading space tells scanf to skip and ignore all leading white-space character, of which newline is one such character.
Note that most format specifiers for scanf automatically skip and ignore leading white-space. For example %s will do that, which means your second version with scanf("%s",s) doesn't need the getchar() call.
Also note that this should have been easily deduced by spending five minutes in a debugger to step through the code statement by statement while monitoring variables and their values.
Then for s == "yes". What happens here is that the array s will decay to a pointer to its first element, as will the literal string, and then you compare these pointers to see if they are the same, which they will most likely never be.
It's somewhat simplified equivalent to this:
char yes_literal[4] = "yes";
if (&s[0] == &yes_literal[0]) ...

ERROR HANDLING OF CHARACTER DATA TYPE IN C PROGRAMMING

If the user would enter an invalid input, the program will ask the question again until the user enters a valid input. The code below performs it however, it executes the command twice:
void error_checking(){
char input;
printf("Enter letters from a to e");
scanf("%c", &input);
if((input<102) || (input>96)){
printf("Valid input");
} else {
error_checking():
}
int main(){
error_checking();
}
Use
scanf(" %c", &input);
^^^
instead of
scanf("%c", &input);
^^
Otherwise the function scanf will read the new line character '\n' that corresponds to the pressed key Enter.
Also you firgot the closing brace of the function.
And it is a bad idea to use magic numbers like
if((input<102) || (input>96)){
And at least you have ti write
if((input<102) && (input>96)){

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"

C Programming: Scanf in while loop only reads input once and then terminates

I am new in C programming and I am currently learning about while loops. The problem I have is, that the while loop must continue until the user wishes to terminate the while loop. But when i run my code it seems that scanf() only once scans for input and the while loops terminates afterwards and I don't know why.
int main(void) {
setbuf(stdout, NULL);
char answer = 'y';
while (answer == 'y') {
printf("continue? (y/n): ");
scanf("%c", &answer);
}
return 0;
}
You need to consume the newline character.
Change
scanf("%c", &answer);
to
scanf(" %c", &answer);
Every character other than y terminates the loop. If you hit y<newline>, the y will cause the loop to run one more time and then the newline will terminate the loop.
The basic problem is that you are reading one character when you actually want to read one line.

Unable to break out of "while" loop - C

I'm trying to implement a simple while loop to let the user enter multiple marks without having to reload the application, for some reason no matter what i seem to enter it always loops.
I've looked using the debugger and it doesn't seem to accept the final scanf() asking whether to repeat itself or not.
int mark = 0;
char grade;
char choice = 'y';
while(choice == 'y')
{
//Request input
printf("enter a mark: ");
scanf("%d", &mark);
//Assess mark
grade = assess(mark);
//Output result
printf("That equals ");
printf("%c", grade);
printf(" when graded\n");
//Repeat?
printf("Again?...\n");
fflush(stdin);
scanf("&c", &choice);
}
I've also tried it with a do - while loop and still no joy, any idea where the problem may lie?
At least two problems:
fflush(stdin);
is undefined - you can only flush output streams. And:
scanf("&c", &choice);
should be:
scanf("%c", &choice);
I think last line should be
scanf("%c", &choice);
instead of
scanf("&c", &choice);
fflush() is only defined for output streams. The comp.lang.c FAQ does not recommend using it for stdin.
Also, as others have noted, use scanf("%c", &choice); to read the choice.
Try scanf("%c", &choice);.
Note that scanf returns the number of inputs matched, so you should really check the return value. If the input does not, for som reason, map to a character, your variable might be unchanged. Before the call to scanf, set choice to something != 'y', so that you only continue if a y is input.

Resources