I have written two programs. In the first one I'm not using getchar to take a character from keyboard, in this case, the compilation is completely missing the second scanf. So to overcome this I have used getchar. In this case I'm successfully able to give input but comparison is not happening. Though I have given input as "d" and "d" output is "bye" only.
#include<stdio.h>
main(){
char c,f;
printf("e");
scanf("%c",&c);
printf("one more");
scanf("%c",&f);
if(c=='d'&&f=='d')
printf("hi");
else
printf("bye");
}
with getchar
#include<stdio.h>
main(){
char c,f;
printf("e");
scanf("%c",&c);
printf("one more");
scanf("%c",&f);
getchar();
if(c=='d'&&f=='d')
printf("hi");
else
printf("bye");
}
The new line character will remain in standard input as it will not be consumed by the scanf("%c"). This means the second scanf() reads the newline charcacter, and not the next input. Changing to scanf(" %c") would be a solution, which will skip leading white space.
Related
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed last month.
int main ()
{
char c;
int choice,dummy;
do{
printf("1. Print Hello\n2. Print World\n3. Exit\n");
scanf("%d",&choice);
switch(choice)
{
case 1 :
printf("Hello\n");
break;
case 2:
printf("World\n");
break;
case 3:
exit(0);
break;
default:
printf("please enter valid choice\n5");
}
printf("do you want to enter more?");
scanf("%d",&dummy);
scanf("%c",&c);
}while(c=='y');
}
tried removing int dummy variable and dummy input, program exits without taking any character input. how is this helping the code to not to exit ?
Whoever wrote this doesn't understand how scanf format specifiers work.
The first call to scanf uses the %d format specifier. This reads and discards any leading whitespace, then reads a decimal integer. Assuming you pressed ENTER after typing in this integer, a newline character will be left in the input buffer.
The %c format specifier reads the first character in the input buffer but does not strip off trailing whitespace. So without the prior call reading dummy, this will read the newline that was stuck in the input buffer previously into c. That causes the comparison c=='y' to be false so the loop exits..
The extra call to scanf for dummy reads and discards the newline left in the input buffer and wait for an integer to be read. Presumably, the user will enter y or n given the prompt, so that call to scanf will not read anything more and will return 0, indicating that nothing matched. The following scanf then reads the y or n.
The proper way to handle this is to add a space before the %c format specifier to absorb leading whitespace instead of adding a "dummy" call:
printf("do you want to enter more?");
scanf(" %c",&c);
The scanf("%d",&dummy) removes a newline so the subsequent scanf("%c",&c); works. Otherwise, it will take \n as its character.
The "extra" newline comes from the fact that it is left in the input stream by the original: scanf("%d",&choice);
To fix, remove the dummy related code and do:
scanf(" %c",&c);
Note the preceding space in the format. This tells scanf to skip over whitespace (which includes newlines).
The fully corrected code is:
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
char c;
int choice;
do {
printf("1. Print Hello\n2. Print World\n3. Exit\n");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Hello\n");
break;
case 2:
printf("World\n");
break;
case 3:
exit(0);
break;
default:
printf("please enter valid choice\n5");
}
printf("do you want to enter more?");
scanf(" %c", &c);
} while (c == 'y');
return 0;
}
I write a piece of code to help myself understand how things work when stdin and stdout involved.
Here is my code:
#include<stdio.h>
#include<stdlib.h>
void prompt(){
int i=0;
printf("please select:\n"); //string1
printf("1.input\n2.print\n3.Exit\n"); //string2
scanf("%d",&i);
switch(i){
case 1:
printf("Data input!\n");
break;
case 2:
printf("data printed!\n");
break;
case 3:
exit(0);
case 10:
printf("Newline detected!"); //string3
default:
printf("Please input a valid number!(1-3)"); //string4
}
}
int main()
{
while(1)
prompt();
return 0;
}
What I expect this code to do is:
prompt me for input;
then I enter a number 4,which is out of the cases;
so the default case will be matched and the string 'Please input a valid...'(string 4) will be printed.
as there is still a newline character left in the stdin buffer, in the next loop,
the variable 'i' will automatically get a newline character, which is 10 in ACSII
So after printing out 'please select..1.input\n2.print....',, a string 'Newline detected!'(string 3) will be immediately printed out.
And then the code goes into the third loop, and prompt me for input....
But that never happen. I cannot see any 'Newline detected!" in the output even if I enter a number 4, which is out of the cases.
Anyone can elaborate how this snippet work exactly?
By the way: I originally assume that when there is something printed in the stdout, the stdin buffer will be flushed automatically. But some fact proved me wrong. Is my assumption true or false?
Also, when I enter a character(for example, a g) rather than a number, I got string 1, string 2, sring 4 printed in the screen infinitly. Why is that?
#######################################################################3
Edit: After viewing the answer, I make another snippet, to help understand.
#include<stdio.h>
#include<stdlib.h>
void output();
int main()
{
int i;
printf("Enter a number here:\n");
scanf("%d",&i);
output();
return 0;
}
void output(){
char a;
if (scanf("%c",&a)!=1){
printf("scanf error!!");
exit(1);
}
switch(a){
case 'a':
printf("an char a is entered");
break;
case 'b':
printf("an char b is entered");
break;
default:
printf("%c",a);
printf("other thing is entered");
}
}
whatever you enter the first time the program prompt you, you will never get your second prompt. For example, when the program prompt you for the first time, if you enter a number 4, then you will get a newline and a string "other thing is entered" printed on you screen. Why is that?
as there is still a newline character left in the stdin buffer, in the next loop, the variable 'i' will automatically get a newline character, which is 10 in ACSII
So after printing out 'please select..1.input\n2.print....',, a string 'Newline detected!'(string 3) will be immediately printed out.
That is not correct. When you use
scanf("%d",&i);
all white spaces are ignored, which includes the newline.
And then the code goes into the third loop, and prompt me for input....
Now you know it stays in the second loop, waiting for a number to be entered.
I originally assume that when there is something printed in the stdout, the stdin buffer will be flushed automatically. But some fact proved me wrong. Is my assumption true or false?
That assumption is false. stdout is flushed when you wait for input from stdin.
Also, when I enter a character(for example, a g) rather than a number, I got string 1, string 2, sring 4 printed in the screen infinitly. Why is that?
That's because the program is not able to read the character when it executes the line:
scanf("%d",&i);
The character stays in the input stream. You don't have any code to remove that character from the input stream. That makes the program stay in an infinite loop.
as there is still a newline character left in the stdin buffer, in the
next loop, the variable 'i' will automatically get a newline
character, which is 10 in ACSII
Wrong. %d will get a integer until a newline or a space is encountered and the newline character in the buffer will not be consumed by the next scanf()
So always check the return value of scanf()
if(scanf("%d",&i) != 1)
{
printf("scanf failed\n");
return 1;
}
As a side note:
case 10:
printf("Newline detected!");
There is a a break missing in this case.
Addressing the second program in the question, here's a mildly revised version. It prints more information, and uses strict prototypes.
#include <stdio.h>
#include <stdlib.h>
void output(void);
int main(void)
{
int i;
printf("Enter a number here:\n");
if (scanf("%d", &i) == 1)
printf("Read %d OK\n", i);
output();
return 0;
}
void output(void)
{
char a;
if (scanf("%c", &a) != 1)
{
printf("scanf error!!");
exit(1);
}
printf("Character %d (%c) entered\n", a, a);
switch (a)
{
case 'a':
printf("an char a is entered\n");
break;
case 'b':
printf("an char b is entered\n");
break;
default:
printf("%c", a);
printf("other thing is entered\n");
break;
}
}
Example runs:
$ ./stdin
Enter a number here:
23499911
Read 23499911 OK
Character 10 (
) entered
other thing is entered
$ ./stdin
Enter a number here:
2A
Read 2 OK
Character 65 (A) entered
Aother thing is entered
$ ./stdin
Enter a number here:
19b
Read 19 OK
Character 98 (b) entered
an char b is entered
$ ./stdin
Enter a number here:
999a
Read 999 OK
Character 97 (a) entered
an char a is entered
$
Note that in the first run, the stray character is the newline after the second 1 digit, character code 10. This is what you should get.
Do make sure your output print operations end with a newline (so that it appears in a timely manner). If you don't, your output may be held up indefinitely.
Do you mean that the scanf() function will not strip the newline character in the stdin buffer?
The scanf("%d", &i) certainly doesn't. The scanf("%c", &a) does. When scanf() completes a conversion, it puts the character that is not part of the conversion back into the input stream ready for the next input operation. So, it doesn't matter whether there's a space, a letter or a newline after the number, that character is left ready for the next input operation to read it. Most scanf() operations skip leading white space. There are three exceptions: %c, %n and %[…] (scansets). They do not skip leading white space.
The following code is not working properly.
scanf and printf statements in the ques2() function are not working in execution. please help me with it.
void main()
{
printf("\t\t\t\t\tKBC");
ques1();
}
void ques1()
{
char c;
printf("\nQ1 WHAT IS THE CAPITAL OF INDIA?");
printf("\na. Delhi \tb. Kolkata");
printf("\nc. Rome \td. China\n");
scanf("%c",&c);
if(c=='a')
{
ques2();
}
else printf("wrong answer");
}
ques2()
{
printf("ques2");
char d;
scanf("%c",&d);
printf("%c",d);
ques3();
}
ques3()
{
printf("ques3");
char d;
scanf("%c",&d);
printf("%c",d);
}
When you use:
scanf("%c",&c);
the newline character is still left in the input stream after the character is read. Next time such a statement is used, the newline character is read into c. If you want to skip leading whitespaces, replace the format in those to " %c".
scanf(" %c",&c);
Make that change in ques1, ques2, and ques3.
Update, in response to OP's comment
When you use
scanf("%c",&c);
If your type a followed by Enter, then the first scanf stores 'a' in c. The second scanf stores a '\n' in c.
When you use
scanf(" %c",&c);
all leading whitespace characters are skipped. Hence, the '\n' from the input stream is not read into c.
I got another answer to the question. There is another method of clearing memory of the buffer i.e fflush(stdin) before scanf statement
this function clears anything that is in the buffer and then allow us to use scanf simply.
Currently im trying to learn simple C Programs. But, i came into this situation :
#include<conio.h>
#include<stdio.h>
void main()
{
char c;
int tryagain=1;
while(tryagain>0){
printf("Enter the Character : ");
scanf("%c",&c);
printf("You entered the character \"%c\" and the ascii value is %d",c,c);
getch();
clrscr();
tryagain=0;
printf("You want to Trry again Press 1 : ");
scanf("%d",&tryagain);
clrscr();
}
}
The program is fine when user first enter a character. And, when it ask to continue. And, user enter 1 then it is behaving weired. It automatically input blank character and prints the ascii and goto the same place.
How can i resolve this? And, specially, Why is the reason for this?
And, Im sorry about my poor english!
Thank you in Advance.
When you use
scanf("%d",&tryagain);
the number is read into tryagain but the newline character, '\n', is still left on the input stream. The next time you use:
scanf("%c",&c);
the newline character is read into the c.
By using
scanf("%d%*c",&tryagain);
the newline is read from the input stream but it is not stored anywhere. It is simply discarded.
The issue is that you are reading a single number in the second scanf, but user inputs more than a single number there, the user also input a new line character by pressing .
User enters "1\n". Your scanf reads "1", leaving out "\n" in the input stream. Then the next scanf that reads a character reads "\n" from the stream.
Here is the corrected code. I use getc to discard the extra new line character that is there.
#include <stdio.h>
void main()
{
char c;
int tryagain = 1;
while (tryagain > 0) {
printf("Enter a character: ");
scanf("%c", &c);
printf("You entered the character \"%c\" and the ascii value is %d\n", c, c);
tryagain = 0;
printf("If you want to try again, enter 1: ");
scanf("%d", &tryagain);
// get rid of the extra new line character
getc(stdin);
}
}
Also, as a side note, you use conio.h which is not part of standard C, it's MS-DOS header file, thus it's not portable C you are writing. I have removed it from my code, but you might wish to keep it.
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 3 years ago.
It is a statement given in K&R that printf() and putchar() can be interleaved. If it true then why is the following code not giving the required output:-
#include"stdio.h"
void main()
{
char c,d;
printf("Enter the first character\n");
scanf("%c",&c);
printf("%c\n",c);
printf("Enter the second character\n");
d=getchar();
putchar(d);
printf("\n");
}
Whenever I am executing this program, the output is as follows:-
Enter the first character
a
a
Enter the second character
This is the output. This is also happening if I replace printf() by putchar() and scanf() by getchar(). Why is this happpening?
The first scanf leaves in the input buffer the \n resulting from the Return press, so your second getchar() will acquire this \n instead of acquiring another character from the user.
If you want to skip that newline character, you can either instruct the scanf to "eat" it:
scanf("%c\n",&c);
or "eat it" directly with a call to getchar():
scanf("%c",&c);
getchar();
(notice that these are not exactly equivalent, since the second snippet will eat whatever character happens to be in the buffer, while the first one will remove it only if it's a \n)
You can correct your code like this:
#include <stdio.h>
int main() {
char c, d;
printf("Enter the first character\n");
scanf("%c\n", &c); // Ask scanf to read newline and skip
printf("%c\n", c);
printf("Enter the second character\n");
d = getchar();
putchar(d);
printf("\n");
return 0;
}
You are getting two a's because you type one in which is echoed to the console and then you print it out.
flush the stdin before using getchar()..
In turbo, use fflush()..
In gcc, use __fpurge(stdin)..(this is available in <stdio_ext.h> header)..
Flushing the standard input before scanning anything will solve your issue..