Reputation: 21
I cant figure out whats wrong. Am i using format specifiers in wrong way? Someone please help i am very new to coding.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char name[20];int age;char grade;double gpa;char area[10];
printf("User Input\n");
printf("Enter your name: ");
fgets(name,20,stdin);
printf("Your name is %s\n",name);
printf("Enter your age: ");
scanf("%d\n",&age);
printf("Your age is %d\n",age);
printf("Enter you grade: ");
scanf("%c\n",&grade);
printf("Your grade is %c\n",grade);//Why is this giving an int output?
printf("Enter your gpa: ");
scanf("%f\n",&gpa);
printf("Your gpa is %f\n",gpa);
printf("Enter your area: ");
scanf("%s\n",&area);
printf("Your area is %s",area);//This shows grade input
return 0;
}
Upvotes: 1
Views: 622
Reputation: 123458
Some things to remember about scanf
:
Most conversion specifiers like %s
, %d
, and %f
will skip over leading whitespace - %c
and %[
will not. If you want to read the next single non-whitespace character, use " %c"
- the leading blank tells scanf
skip over any leading whitespace before reading the next non-whitespace character;
For what you are trying to do, you should not use \n
in your format strings - it will cause scanf
to block until you enter a non-whitespace character;
You do not need to use the &
operator on array expressions like area
; under most circumstances, array expressions are converted to pointer expressions1. Honestly, you should read area
the same way you read name
, using fgets
(and you should always check the result of fgets
), or you should specify the maximum field width in the specifier: scanf( "%9s", area );
(a 10-element array can hold up to a 9-character string, since one element has to be reserved for the string terminator);
You should get in the habit of checking the result of scanf
- it will return the number of successful conversions and assignments. For example, scanf( "%d %d", &x, &y )
will return 2 if both x
and y
are read successfully. It will return EOF
if end-of-file is signaled or there's a read error.
scanf
will read up to the next character that doesn't match the conversion specifier - IOW, if you're using %d
, then scanf
will skip over any leading whitespace, then read up to the next character that isn't a decimal digit. That character is left in the input stream. This means if you're using %d
and type in 123e456
, scanf
will read up to that 'e'
character and assign 123
to the target. If you try to read again with %d
, scanf
will immediately stop reading on that e
and return 0 without assigning anything to the target (this is called a matching failure). This will continue until you remove that 'e'
from the input stream (such as with getchar
or fgetc
or scanf
with the %c
specifier, etc.
You need to make sure the types of the arguments match the format specifier. %s
expects an argument of type char *
, %d
expects int *
, %f
expects float *
. %x
expects unsigned int *
, %lf
expects double *
, etc.
Upvotes: 0
Reputation: 21532
You use fgets
correctly when reading name
. I'd recommend also using fgets
for all your other inputs, and then parsing the intended values out of them. For example:
char age_str[20];
fgets(age_str, 20, stdin);
age = strtol(age_str, NULL, 10);
This is preferable to using scanf
directly for non-string inputs since if input fails to match a format string, it will remain in stdin
and screw up the other scanf
calls.
If you would like to use scanf
correctly:
do
/while
loop for this." %c"
, so that any whitespace remaining in stdin
will be skipped over.Upvotes: 1