#include <stdio.h>
int main ()
{
char loop='y';
while(loop != 'n') {
printf("loop? ");
scanf("%c", &loop);
if(loop != 'y') {
loop='n';
}
}
return 0;
}
If I type in 'y' he restart the while-loop but ignores the scanf the second time and end the loop after that. Can anyone help?
Make sure the scanf discards the newline. Change it to:
scanf(" %c", &loop);
^
You probably had to enter a newline so the input goes to your program, right? The second time your loop executes it reads that newline character, which was "waiting" to be read and automatically exits the loop ('\n' != 'y'). You can make scanf ignore whitespace by using this format string instead:
" %c"
One solution can be the use fflush(stdin) after the scanf() statement to clear the input buffer.
Related
I have wrote a small code to get value from Fahrenheit to Celsius. I wanted to keep inputting data until I press any other key than 'y'. But this loop doesn't work that way and stops after one iteration.
#include <stdio.h>
int main()
{
char ch='y';
int far, cen;
do {
printf("again\n");
scanf("%d",&far);
//cen = (5.0/9.0)*(far-32);//integer division will truncate to zero so we can make 5/9 to 5.0 / 9.0
cen = (5*(far-32))/9;//or this way we can use this formula
printf("\n%d\t%d",far, cen);
printf("ch=%c",ch);
scanf("%c",&ch);
}while(ch == 'y');
return 0;
}
What is the problem here?
P.S
I added a line and made a new code like this
#include <stdio.h>
int main()
{
char ch='y';
int far, cen;
do {
printf("again\n");
scanf("%d",&far);//here we press carriage return. this value is in stdin
//cen = (5.0/9.0)*(far-32);//integer division will truncate to zero so we can make 5/9 to 5.0 / 9.0
cen = (5*(far-32))/9;//or this way we can use this formula
printf("\n%d\t%d",far, cen);
scanf("%c",&ch);//putting a space before %c makes the newline to be consumed and now it will work well
if((ch == '\r')|| (ch == '\n'))
printf("1\n");
printf("ch=%c",ch);//this takes the carriage return in stdin buffer
}while(ch == 'y');
return 0;
}
I need to know carriage return here is \r or \n?
When the value for scanf("%d",&far); is entered and press enter, the scanf stores the carriage return in the buffer. When it encounters the second scanf in the code scanf("%c",&ch); it takes the carriage return present in the buffer as the input to 'ch'. So it doesn't wait for the user input.
Please have a look at the post here
As indicated in one of the reply the solution is to put a space in scanf
scanf(" %c",&ch);
You should always check the return value of scanf. Your first use of scanf may fail if the user does not enter a valid integer, in which case, you are using far without initialising it (which is undefined behaviour). scanf returns the number of items that were successfully scanned. If you are requesting scanf to scan one integer, then it should return 1 if it successfully managed to scan an integer.
int scanresult = scanf("%d", &far);
if (scanresult != 1)
{
puts("Invalid input or unexpected end of input");
return 1;
}
In addition, the %c conversion specifier is unique in that it does not cause scanf to gobble up any preceding whitespace unlike the other conversion specifiers. To force scanf to gobble up the whitespace (such as linefeeds, carriage returns, spaces, tabs etc), simply put a space character before the %c, e.g.
scanresult = scanf(" %c", &ch);
For scanf, the space character is actually a directive to parse and skip all whitespace.
This is because of the previous newline character remaining in the buffer. You can simply replace scanf by this line:
while((ch = getchar()) == '\n');
You'll be needing the same technique in combination with ungetc() in many occasions.
Add fflush() function, just above scanf("%c", &ch). Because buffer of CONSOLE INPUT stores characters that not returned to program. Which is ENTER pressed in previous scanf:
#include <stdio.h>
int main() {
char ch='y';
int far, cen;
do {
printf("again\n");
scanf("%d",&far);
//cen = (5.0/9.0)*(far-32);//integer division will truncate to zero so we can make 5/9 to 5.0 / 9.0
cen = (5*(far-32))/9;//or this way we can use this formula
printf("\n%d\t%d",far, cen);
printf("ch=%c",ch);
scanf("%c",&ch); // This scanf will be ignored, because loads last
// character from buffer that can be recognized
// by scanf which is pressed "ENTER" from previous scanf
printf("%d", ch) // Shows 10, which is ASCII code of newline
fflush(stdin); // Clear buffer
scanf("%c",&ch); // Now it will prompt you to type your character.
// printf("%c"ch); //Without fflush, it must show 10, which is \n code
}while(ch == 'y');
return 0;
}
if after Y you press "space" or "return" this is the character you will find in %C
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.
Here is the while loop and switch in question (track1 defines a bigger loop not shown here):
while (track6 ==1)
{
printf ("would you like to play again? Y or N?\n");
scanf ("%c", &response);
switch (response)
{
case 'Y' : track6 = 2;
break;
case 'N' : printf ("thanks for playing!\n");
track6 = 2, track1 = 2;
break;
default : printf ("response is case-sensitive and must be either Y or N. your response is invalid. please reenter.\n");
}
}
The output I receive is:
would you like to play again? Y or N?
response is case-sensitive and must be either Y or N. your response is invalid. please reenter.
would you like to play again? Y or N?
(prompts for input and then executes correctly)
Seems like it is executing the first printf, skipping the scanf, executing the default, going back to the top of the loop and running properly from there. Any idea why? This is only my 3rd week programming so layman's terms are appreciated.
I think it's issue with scanf as it reads enter first - try getchar() or add a space character in scanf like " %c"
scanf (" %c", &response);
Seems like it is executing the first printf, skipping the scanf, executing the default, going back to the top of the loop and running properly from there. Any idea why?
No. Seems like it is executing the first printf statement, reading the newline (\n) character left behind by the previous scanf, going back to the top of the loop and running properly from there.
One possible solution to eat up this newline character is to change
scanf ("%c", &response);
to
scanf (" %c", &response);
^
|
add a space here to eat up '\n'
But this will work if and only if input from the user is either Y or N. If in case a user input YES or NO, more than one character (excluding \n) then your program should have to eat all these extra character to run the program properly. For this, use a loop just after the scanf in while;
printf ("would you like to play again? Y or N?\n");
scanf ("%c", &response);
while ((response = getchar()) != '\n' && response != EOF)
;
With
scanf ("%c", &response); you need to skip trailing newline from previous scanf
So use:
int ch;
while ((ch = getchar()) != '\n' && ch != EOF); //eats '\n'
after scanf
You need to flush the input buffer before using scanf to input a character.Use simply getchar().It'll eat the '\n' character present in the buffer.
#include <stdio.h>
void main()
{
char ans='n';
do
{
printf("\n Enter yes or no:");
scanf("%c",ans);
printf("\n entered %c",ans);
}while(ans == 'y');
}
As do while the loop is getting exccuted and that scanf is working and prnting my answer (say my answer is y) , its coming for 2nd time but not doing the scan and getting exited . May i know the reason for this ? why it is happening and what is the correct way to handle the infinite loop.
First up, you're missing a & in the scanf:
scanf("%c", &ans);
^
Second, you're not handling the newline, and the %c format specifier doesn't ignore blanks. So you read a character, press return, and the next scanf is immediately satisfied by that \n. To ignore blanks in scanf try:
scanf(" %c", &ans);
^
Not only are you missing the &address-of operator as indicated in other answers, but you're also missing the return value checks. Consider if a user presses CTRL+Z in Windows, or CTRL+d in Linux, to close stdin. Your loop would run infinitely and freeze your app ;)
if (scanf("%c", &ans) != 1) {
break;
}
Alternatively, I would suggest using getchar because it's far cleaner:
int main(void) { /* NOTE: There is no "void main()" entrance point in C. main should always return 'int'. */
int c;
do {
c = getchar();
} while (c == 'y');
return 0;
}
Use fflush(stdin) to flush those return feeds.
But when you are inputting a single character, then why not use getchar()?
EDIT:
As correctly pointed out by cnicutar here, fflush(stdin) has undefined behaviour. There doesn't seem to be any inbuilt function to take care of that and hence must be taken care of in the code itself.
One example could be:
int ch;
while ((ch = getchar()) != '\n' && ch != EOF);
Thanks for pointing that out there!
#include <stdio.h>
int main ()
{
char loop='y';
while(loop != 'n') {
printf("loop? ");
scanf("%c", &loop);
if(loop != 'y') {
loop='n';
}
}
return 0;
}
If I type in 'y' he restart the while-loop but ignores the scanf the second time and end the loop after that. Can anyone help?
Make sure the scanf discards the newline. Change it to:
scanf(" %c", &loop);
^
You probably had to enter a newline so the input goes to your program, right? The second time your loop executes it reads that newline character, which was "waiting" to be read and automatically exits the loop ('\n' != 'y'). You can make scanf ignore whitespace by using this format string instead:
" %c"
One solution can be the use fflush(stdin) after the scanf() statement to clear the input buffer.