scanf gets the input of the previously excecuted getchar() - c

I am using getchar() in order to read characters and put them on a table, as well as scanf in order to get an integer.
The problem with the scanf() is that it doesn't wait for the users' input but reads from the buffer the last character given on the previous line, with getchar().
I tried sscanf, fflush(stdin); etc but I'm getting still the same behavior.
#include <stdio.h>
#include <stdlib.h>
main()
{
int i, choice, tmp_day, tmp_month;
char name[5];
printf("insert choice(1-3):\n");
scanf("%d",&choice);
printf("name: ");
for (i=0;i<5;i++) name[i]=getchar();
name[5] = '\0' ;
printf("day (1-31): ");
scanf("%d",&tmp_day);
printf("month (1-12): ");
scanf("%d",&tmp_month);
printf("\n%d %d", tmp_day, tmp_month);
}
Any idea?
Thanks in advance.

Detailed discussion about fflush(stdin) which not necessarily portable.
http://c-faq.com/stdio/gets_flush2.html

After each scanf use this statement:
fflush(stdin);

Related

Why is fgets waiting for input before it's even called?

I'm trying to write a simple program to read an integer and then a string, then print both to standard output. Ideally, the execution should look something like this:
Input the number.
> 10
Input the string.
> a string
number: 10
string: a string
However, when I run the program, it freezes after the call to scanf() until more input is provided.
Input the number.
> 10
a string
Input the string.
>
number: 10
string: a string
Why is it waiting for input before fgets() is ever called?
#include <stdio.h>
int main()
{
int number;
char string[32];
printf("Input the number.\n> ");
scanf("%d\n", &number);
printf("\nInput the string.\n> ");
fgets(string, 32, stdin);
printf("\nnumber: %d\nstring: %s\n", number, string);
}
From a previous post...
https://stackoverflow.com/a/5918223/2203541
#include <stdio.h>
int main()
{
int number;
int c;
char string[32];
printf("Input the number.\n> ");
scanf("%d", &number);
do
{
c = getchar();
} while (c != '\n');
printf("\nInput the string.\n> ");
fgets(string, 32, stdin);
printf("\nnumber: %d\nstring: %s\n", number, string);
}
"Why is fgets waiting for input before it's even called"
fgets() does not act until it is called, but if when called, and if pointing to stdin and there is content remaining in the stdin stream, it will consume it immediately. If that contents contained EOF, n-1, OR a newline (read link) execution flow will continue.
The problem here is that scanf() (called prior to fgets()) is notorious for doing exactly what it is asked to do. For example, upon user entering 12<return> two recognizable items are entered into stdin, digits and a newline but by using "%d" as the format specifier, only the first of those items is consumed, leaving the \n hanging, until the very next call to fgets(), which accepts it as input, allowing execution flow to resume immediately (as described above), causing the apparent skip you are seeing.
[This is one (of several) examples that will provide a work around for the scanf() issue:
Change this:
printf("Input the number.\n> ");
scanf("%d", &number);//leaves the newline
To this:
char c;
...
printf("Input the number.\n> ");
scanf("%d%c", &number, &c);//consumes the newline
From comments:
"is there a way to use fgets to read an integer"
Yes, I prefer fgets() coupled with your favorite string to number converter. (There are several) The simplest is this:
char cNum[10];
int num;
printf("Input the number.\n> ");
if(fgets(cNum, sizeof cNum, stdin))
{
num = atoi(cNum);
}
else //handle error
See also strtol() for a more robust solution.
Alright, so I played around with it some more and did a little more studying on scanf() format syntax, and figured out a solution. Apparently, putting the whitespace character at the end of my scanf call there tells it to keep reading until it finds something AFTER the whitespace, so of course it would hang up there until you give more input.
Remove the whitespace character in the scanf formatter, and add a leading space to the following scanf call.
The reason I had used fgets originally was so I could specify a buffer length to avoid overflow. Apparently, the same effect can be achieved using %32s in the scanf call. The fixed code looks like this:
#include <stdio.h>
int main()
{
int number;
char string[32];
printf("Input the number.\n> ");
scanf("%d", &number);
printf("\nInput the string.\n> ");
scanf(" %32s", &string);
printf("\nnumber: %d\nstring: %s\n", number, string);
}

scanf is skipped (?)

I tried to do a small Worker Register, but it skips completely the second scanf, which gets address value. I am a beginner, so I do not know what I am doing wrong. Here is the code:
#include <stdio.h>
int main()
{
// var
char n[256], ad[256]; // n - Name, ad - Address
int i, ag; // i - Income, ag - Age
// code
printf("Welcome to the Worker Register\n\nWorker Data\n\nName: ");
scanf("%255[^\n]", n);
printf("Address: ");
scanf("%255[^\n]", ad);
printf("Age: ");
scanf("%d", &ag);
printf("Income: R$");
scanf("%d", &i);
printf("Worker %s\nAddress: %s\nAge: %d\nIncome: R$%d", n, ad, ag, i);
return 0;
}
I really appreciate any help you can provide!
Nad's hack of adding a getchar() seems to fix it, but I wouldn't use scanf for reading strings if I were you.
It's nicer to use fgets() reading strings instead. scanf on a string is problematic. See: Reading a string with scanf
e.g.
#include <stdlib.h>
...
printf("Welcome to the Worker Register\n\nWorker Data\n\nName: ");
fgets(n, 256, stdin);
...
Regarding the size parameter in fgets(). The man page states:
fgets() reads in at most one less than size characters from stream
and
stores them into the buffer pointed to by s. Reading stops after an
EOF or a newline. If a newline is read, it is stored into the buffer.
A terminating null byte ('\0') is stored after the last character in
the buffer.
Therefore you enter the size of the buffer and ignore the null byte as fgets will do that work for you.
Just simply add a getchar(); To be honest, I don't know why but this has happened to me plenty of times in school. It seemed to fix it :)
code:
#include <stdio.h>
int main()
{
// var
char n[256], ad[256]; // n - Name, ad - Address
int i, ag; // i - Income, ag - Age
// code
printf("Welcome to the Worker Register\n\nWorker Data\n\nName: ");
scanf("%255[^\n]", n);
printf("Address: ");
getchar();
scanf("%255[^\n]", ad);
printf("Age: ");
scanf("%d", &ag);
printf("Income: R$");
scanf("%d", &i);
printf("Worker %s\nAddress: %s\nAge: %d\nIncome: R$%d", n, ad, ag, i);
return 0;
}
"%255[^\n]" meant input up to newline(accepts inputs other than newline).(The newline isn't included.)
So, there is a newline in the input buffer(of stdin),
second scanf (scanf("%255[^\n]", ad); ) also accepts inputs other than newline,
So, It will not be entered.
Therefore you need to consume the newline in first scanf.
E.g scanf("%255[^\n]%*c", n); %*c ignores one character(That is the newline).
Since %d of 3rd scanf skips the previous white-spaces, %*c isn't necessary for 2nd scanf.

C cannot read string after I read an integer [duplicate]

This question already has answers here:
C: Multiple scanf's, when I enter in a value for one scanf it skips the second scanf [duplicate]
(7 answers)
Closed 7 years ago.
Below is my source code. After I read the integer, the program should wait until I type a string and then press enter. However, as soon as I enter the integer, the program exits. Can you tell me where is my fault?
#include <stdio.h>
#include <string.h>
int main()
{
int n;
char command[255];
scanf("%d", &n);
fgets(command, 255, stdin);
return 0;
}
I mention that I also tried to use gets(command), but I get the same result.
There is a trailing newline, since you press ENTER after the integer. Eat it by changing this:
scanf("%d", &n);
to this:
scanf("%d ", &n); // this will eat trailing newline
As chux said, scanf("%d ", &n) will not return until the user enters the number and some following non-white-space.
Relevant question: C: Multiple scanf's, when I enter in a value for one scanf it skips the second scanf
Also I have in mind my example: Caution when reading char with scanf .
Also, as Marco stated, you could use: scanf("%d\n", &n);, which targets the newline specifically.
There is also this possibility:
#include <stdio.h>
#include <string.h>
int main()
{
int n;
char command[255], newline;
scanf("%d", &n);
scanf("%c", &newline); // eat trailing newline
fgets(command, 255, stdin);
return 0;
}
However, I would personally use two fgets() and no scanf(). :)
The scanf() leaves newline character after the integer, and fgets() will read it and exit.
Try reading all input with fgets().
#include <stdio.h>
#include <string.h>
int main()
{
char buffer[255];
int n;
char command[255];
fgets(buffer, sizeof(buffer), stdin);
sscanf(buffer, "%d", &n);
fgets(command, sizeof(command), stdin);
return 0;
}
Typing "3c" and pressing enter in your console will make your input buffer stdin look like this: {'3','c','\n'} and would work, since scanf consumes the 3, fgets consumes the c, and the \n would be where fgets stops.
But if you type "3" and press enter, scanf will consume the 3, and the newline character will be left, causing fgets to consume no characters.

Why gets() function skips when preceded by scanf("%d")?

I want to make a program which take Roll No and Full name as input and simply display it
My code is . this code skip scaning value of n through gets function. Why this error occur and how to over come this?
#include<stdio.h>
#include<conio.h>
void main()
{
int r;
char n[30];
printf("enter your roll no");
scanf("%d",&r);
printf("enter your full name");
gets(n);
printf("roll no is %d ",r);
printf("name is %s ",n);
getch();
}
while the below code scan the first gets value and skips the second one.
#include<stdio.h>
#include<conio.h>
void main()
{
int r;
char n[30], f[30];
printf("enter your roll no");
scanf("%d",&r);
printf("enter your full name");
gets(n);
printf("enter your full name of your father ");
gets(f);
printf("roll no is %d ",r);
printf("name is %s ",n);
printf("father name is %s ",f);
getch();
}
The code DOES NOT skip scanning the value of 'n'.
I believe that when you run the program, you enter the Roll No and then press the ENTER key on your keyboard.
This is the cause.
As soon as you press the ENTER key, the escape sequence '\n' is saved in the array n. Your gets() command is executing perfectly.
In the second case, the variable 'n' stores the escape sequence and the next variable 'f' takes the string you enter next.
To make your code work just enter your scanf statement like this:-
scanf("%d ",&r);
Notice the space after %d.
Try this code-
#include<stdio.h>
int main(void)
{
int r;
char n[30], f[30];
printf("Enter your roll no");
scanf("%d ",&r); // I have inserted a space after %d
printf("Enter your full name");
gets(n);
printf("Enter your full name of your father ");
gets(f);
printf("\nRoll no is %d ",r);
printf("\nName is %s ",n);
printf("\nFather name is %s ",f);
return 0;
}
TIP:- You must try not to use gets() and puts()
You can read more about it here.
The simple solution for the problem is to add fflush(stdin); between scanf(); and gets();
#include<stdio.h>
#include<conio.h>
void main()
{
int r;
char n[30],fn[30];
clrscr();
printf("\nEnter roll ");
scanf("%d",&r);
fflush(stdin);
printf("\nEnter name ");
gets(n);
printf("\nEnter father name ");
gets(fn);
printf("\n\nRoll %d",r);
printf("\nname %s",n);
printf("\nfather name %s",fn);
getch();
}
Using scanf instead of gets will solve your problem:
scanf("%s", n); // Read in your name
Please note that when reading in any string like this you should use safe functions that are passed the length of the string (for example scanf_s from MSDN).
I don't know why it gets skipped but what you could do to avoid any other confusion like fflush(stdin) or fgets etc etc.
Just use gets(string) on the next line. So when it skips the first gets command it goes onto the other one.
Try that
Cheers,
;)
I just had the same problem two hours ago, but to solve this situation easily, all you have to fo is to add a "getchar()" after the "scanf()" and before the "gets()", so that the extra "\n" goes to the "getchar()" and you can type as you want in the next "gets()".
I was also facing the same problem as mentioned above.. so with the help of the answers mentioned here and using hit and trial method, I found that when we press enter after giving input to any variable using scanf(), \n is stored in the next gets() function.. and next time it doesn't take any input from the keyboard.. so to avoid this just use getchar() in between the scanf() nd gets() nd also remember that getchar() takes only 1 character.. so don't give any extra input to scanf() as again this will be stored and will be used in gets() nd the problem will remain the same....
hope this will help..
thank u..

scanf and printf just skips after 1st time

what is the problem here? scanf doesnt seems to working in while loop. i was trying to find out vowel & consonent until user wants.
Here's the code:
#include <stdio.h>
main()
{
char x,c;
do
{
printf("enter\n");
scanf("%c",&x);
if(x=='a'||x=='e'||x=='i'||x=='o'||x=='u')
printf("vowel\n");
else
printf("consonent\n");
printf("do u want to continue ?(y/n)\n");
scanf("%d",&c);
if(c=='n')
printf("thnks\n");
} while(c=='y');
return 0;
}
You are trying to read a character using %d which is wrong. Use %c instead.
Change code to scanf("%c",&c) your original code is getting the y/n entries as digits not characters
Edit:
Probably you are getting the carage return instead of the character try using getc or fgets instead and get the first character.
I think the problem might be here:
scanf("%d",&c);
It should be:
scanf("%c",&c);
Here is the Correct code:
#include <stdio.h>
int main()
{
char x,c;
do
{
printf("enter\n");
scanf("%c",&x);
getchar(); //to remove the \n from the buffer
if(x=='a'||x=='e'||x=='i'||x=='o'||x=='u')
printf("vowel\n");
else
printf("consonent\n");
printf("do u want to continue ?(y/n)\n");
scanf("%c",&c); //Here you were using %d instead of %c
getchar(); //to remove the \n from the buffer
if(c=='n')
printf("thnks\n");
}while(c=='y');
return 0;
}
Both scanfs should be changed like this:
scanf(" %c",&x);
...
scanf(" %c",&c);
Note the space before the %, it's important: it consumes leading whitespace, which includes the endline characters left over in stdin after processing the input.
Please try with this code to run the loop multiple times.
EDIT: Different solution without fflush(stdin). Please define a string of 8 characters as
char str[8];
and modify the code in the loop as
fgets(str, 8, stdin); // To read the newline character
printf("do u want to continue ?(y/n)\n");
scanf("%c",&c);
fgets(str, 8, stdin); // To read the newline character

Resources