void main(){
int a;
scanf("%d",&a); // Need to check there is no character entered
printf("%d",a);
}
Here if i pass abc it will print 0
, if i pass 123abc
it will print 123
, but i need to throw an error in both the conditions.
Here how to check whether only numbers are being entered as input and to throw an error message if character is entered as input. Is it possible to check keeping int as input datatype or should i use char array and check for isalpha condition by traversing the array.
CodePudding user response:
A code that asks for input again if it is not correct:
#include <stdio.h>
int main(void)
{
int number;
printf("Your input: ");
while(scanf("%d", &number)!=1 || getchar()!='\n')
{
scanf("%*[^\n]%*c");
printf("you must enter an integer: ");
}
printf("%d\n", number);
return 0;
}
The first scanf makes the entry, the second empties the keyboard buffer. getchar checks that the next character is the enter key.
CodePudding user response:
You need to check the value returned by scanf
. (That is always true)
#include <stdio.h>
#include <ctype.h>
int
main(void)
{
int a;
char b;
if( (2 == scanf("%d%c", &a, &b)) && isspace(b) ){
printf("%d\n", a);
} else {
fputs("Invalid input!\n", stderr);
}
}
You must always check the value returned by scanf
. In your case (using %d
), if the first character on the input stream is not a digit, scanf
will return 0. If the input is 123x
, scanf
will read the 123 and return 1. If the input is a string that is too long to be represented by an int
, the behavior is undefined.
By using M%c
, you can check the value on the input stream after the integer is read from the stream. In our case, we consider it an error unless that value is whitespace. This will work fairly well for interactive use in which you expect the value to be a newline, but this does not work at all well if the stream ends with a valid integer. In that case, scanf
would return 1, and you would need to add more logic to decide whether or not an error occurred. The solution to that is the same as to all problems involving scanf
: stop using scanf
, because it is a terrible tool.
Also, note that I'm using M
in the format string rather than %d
. You may want to increase that number, but you must have some width modifier to prevent undefined behavior on inputs that can not be represented by an integer. But, in order to know the maximum width modifier you can use, you need to know INT_MAX on the machine, and the actual range of values that can be read in is not the full range of int
. The language only guarantees that INT_MAX is at least 32767, so ]
is unsafe, since the input 99999
would lead to UB. The solution there is the same as the solution to all problems that involve scanf
: stop using scanf
, because it is a terrible tool.
The key to your problem is: check the value returned by scanf to know how many conversions it made. But to emphasize for now the 3rd time: stop using scanf
, it is a terrible tool!
CodePudding user response:
The %d format specifier tells scanf to read a signed decimal integer value. The int data type represents negative integers, zero, and positive integers. Any of the following patterns represent a valid integer:
- Negative sign followed by numeric digits. Example -3
- Positive integers may start with a plus sign and be followed by numeric digits. Example: 73
- Numeric digits not preceded with a plus sign or a negative sign will be read as positive integer values. Example: 9
scanf looks for these types of patterns when converting input to the specified type. As the answers above indicate, the scanf function returns the number of items in the argument list that were successfully read.
#include <stdio.h>
int main(void)
{
int returnValue;
int number;
/*
scanf("%d", &number) will return a value of 1 if it successfully reads an
integer value. Otherwise it will return a value of 0 if it fails to read an
integer value.
The specifier d says to extract any number of decimal digits (0-9),
optionally preceded by a sign ( or -).
Suppose the user enters the following input: -3 followed by the enter key press.
Think of scanf as reading one input character at a time. The first character read
is the minus sign '-'. Since the number may start with a minus, scanf reads the
next character '3'. This is a decimal digit which fits the integer pattern.
The next character is the enter key press '\n' which causes scanf to stop reading
the input. The characters '-' '3' are converted to the integer value -3 and
are stored in the variable named number.
The scanf function successfully read one integer value, so it returns a value
of 1 and stores it in the variable returnValue.
Suppose the user enters the following input: -3.0
The value of -3 is read and stored in the variable number. When scanf reads
the character '.', it stops reading information from the input stream
because this character is not a decimal digit. The value -3 is stored in
the variable number. The scanf function returns a value of 1 because it
successfully read an integer.
The characters '.' '0' '\n' still remain in the standard input (stdin) buffer,
waiting to be read from the input stream. The next time scanf is called
to read from the stream, it will try to read the '.' If the program needs
to read another number, we write code to clear the input stream of all
remaining characters so that scanf does not fail when next trying to read
numeric input.
Suppose the user enters the following input: a-1
The character 'a' is not a numeric digit. It will not be read from the
input stream. scanf will return a value of zero and will not write
write any value into the memory of the variable number.
The characters 'a' '-' '1' \n' all remain in the input stream.
scanf will skip over leading whitespace characters when trying to read an integer.
*/
returnValue = scanf("%d", &number);
printf("number: %d, returnValue: %d\n", number, returnValue);
return 0;
}