I just started learning c programming, my question might be so silly.
I try to create a function to grab user input using scanf(). before that, I will have the menu displayed, and the user should only enter a number. so there is my question, how can I check whether the user enters an integer or character string or any other symbol. and send an error message if they do so?
CodePudding user response:
refer to scanf() manual, they stated that :
The scanf() function returns the number of fields that were successfully converted and assigned. The return value does not include fields that were read but not assigned.
which means like for example , if you have a code like that :
int x;
int numOfAssignedVars = scanf("%d", &x);
then if the user enter a valid number like 2 for example then the value of numOfAssignedVars = 1
but if the user entered a char like s
then numOfAssignedVars = 0
which indicated failure of the conversion
CodePudding user response:
This is a fabulous question.
The answer is: You cannot force the user to give you good input.
You can only detect it and complain (and quit).
Getting the input is the trick, then. In general, you should consider the following mantra:
→ Every time you ask for input, expect the user to press Enter
This makes life a little more predictable:
Get user input using
fgets()
(orgetline()
or any other reasonable function to get a newline-terminated string from the user).Then try to convert the string to the type of object you desire. If it does not convert, then the user supplied bad input and you can complain and rage quit.
For example, suppose you want a floating-point value from the user:
printf( "What... is the airspeed velocity of an unladen swallow? " );
Get the input:
char s[100];
fgets( s, sizeof(s), stdin );
(Don’t forget to complain if the input is bad — in this case, if the answer doesn’t fit in 99 characters:)
char * nl = strpbrk( s, "\r\n" );
if (!nl) complain_and_quit();
*nl = '\0';
On to step two: attempt to convert the string to the proper type:
char * endp;
double speed = strtod( s, &endp );
If it didn’t work, user’s input is bad. Notice, in particular, how we check to see that the entire string was consumed:
if (*endp) complain_and_quit();
(You may want to add consideration for skipping trailing whitespace, which the user may enter as well.)
Otherwise all is good!
if (20.0 <= speed && speed <= 20.1) // give user benefit of rounding off
printf( "Good job!\n" );
else
printf( "Correct answer is 20.1 mph\n" );
More complex inputs require a bit more vetting, but simply having a function to transform the input string to that type or fail is enough to proceed for any given input type.
As a final note, remember that some types may overlap. For example, an int
is also a valid double
. If you need to tell them apart, try the integer conversion first, as 3.14
will fail to convert correctly.
Oh, almost forgot: https://interestingengineering.com/science/monty-python-and-the-holy-grail-airspeed-velocity-of-an-unladen-swallow
CodePudding user response:
scanf is not great for input validation... I would recommend to read input as a string in a buffer. Then use strtol, strtoll, strtod or strtof on that buffer to parse the user input, depending on what you expect. Those functions will tell you if there was an overflow, if there is no conversion possible or if there are characters in the buffer that were not converted.
Look here for the man pages for those functions.
CodePudding user response:
Here is a code with scanf which allows to enter only an integer:
#include <stdio.h>
int main(void)
{
int number;
printf("Your number : ");
while(scanf("%d", &number)!=1 || getchar()!='\n')
{
scanf("%*[^\n]%*c");
printf("You must enter an integer: ");
}
printf("%d\n", number);
return 0;
}
CodePudding user response:
A number in C can be an int, long long, double, float, short int ... etc. Depending on the precision you want.
I will suppose it's a double (since it contains all other types: int, short, float ... etc).
When using scanf(), according to this link
On success, the function returns the number of items of the argument list successfully filled
If you give it a string as an argument, the returned value will be 0. Since 0 float numbers have been detected.
int b = scanf("%d", &i); // b = 1 if given an integer, 0 if it is a string