#include <stdlib.h>
#include <stdio.h>
int main()
{
int age;
printf("Enter your age: ");
scanf("%d", &age);
printf("You are %d years old\n", age);
double gpa;
printf("Enter your GPA: ");
scanf("%lf", &gpa);
printf("Your GPA is %f\n", gpa);
char grade;
printf("Enter your Grade: ");
scanf("%c", &grade);
printf("Your Grade is %c\n", grade);
char name[20];
printf("Enter your Name: ");
scanf("%s", name);
printf("Your name is %s\n", name);
char fullname[20];
printf("Enter your full name: ");
fgets(fullname, 20, stdin);
printf("Your full name is %s\n", fullname);
return 0;
}
In the terminal, this happens:
Enter your age: 18
You are 18 years old
Enter your GPA: 4
Your GPA is 4.000000
Enter your Grade: Your Grade is
Enter your Name: John
Your name is John
Enter your full name: Your full name is
It skips over the grade to ask the name, and it does the same with the full name except the program is finished.
I used this code from a C tutorial video, and I am pretty sure what I have written is basically identical. Please let me know what I should change.
CodePudding user response:
When scanning a single character using %c
, the previous newline character from the user pressing enter on the previous input is consumed. You should add a space before %c
so that it skips the leading whitespace.
scanf(" %c", &grade);
Edit: scanf("%s", name);
can cause buffer overflows. You should use fgets
instead and make sure you leave an extra character for the null terminating character.
CodePudding user response:
Fundamentally, the problem is that scanf
is not consuming whitespace as you expect. When the user enters 4\n
for the gpa, scanf
consumes the 4
and stores a value in gpa
, but it does not consume the \n
. The next call to scanf("%c"
finds the newline and stores it in grade
. Similarly, when the user enters John\n
for the name, scanf
consumes the John
but does not consume the newline. The call to fgets
then reads until it sees a newline: so it reads exactly one character. You need to consume whitespace. The correct thing to do is to stop using scanf
completely (it is difficult to avoid undefined behavior when reading integers and nearly impossible to avoid it when reading floats, and the behavior is often unexpected when used interactively and the input is not correct. For example, experiment with how your program behaves when the user enters 'fourteen' for the age). The simple solution is to consume the whitespace. You could do that with scanf(" %c", &grade);
and by replacing fgets
with scanf(" [^\n]", fullname);
The leading space in the format string causes scanf
to skip over all whitespace. It is tempting to try putting whitespace at the end of the conversion specifier (eg "%d "
), but this is not wise for interactive input. (If you try to read the age with "%d "
, then the scanf will not return until the user enters an age and some other non-whitespace character, so the next prompt will not be written until the user enters something.) The %d
and %f
and %s
conversion specifiers skip over whitespace be default, but %c
and %[
do not.