I need to read a positive number only (unsigned long long), a nothing is more, so I use scanf("%llu", &num);. But it also allows to input negative values.
How to validate positive numbers in this case? The user must input a positive number in [0..2^(64)-1] but he can miss and input a negative value in same interval. But I can't declare a long long variable to check it cuz it can contain 2^64 - 1 totally.
- 71,951
- 46
- 188
- 305
- 7,277
- 11
- 56
- 123
-
4Read as a *string* (e.g. using `fgets()`) and do your validation on it. – P.P Sep 28 '17 at 17:29
-
1Sorry, Imma noobie in C really... How can I convert a string to `unsigned long long` after? – Denis Sologub Sep 28 '17 at 17:30
-
See [string to uint64_t casting with error handling](https://stackoverflow.com/q/46325780/2410359) – chux - Reinstate Monica Sep 28 '17 at 17:39
2 Answers
Read the number as a string with fgets(), then validate it, e.g. with strchr(). Finally use strtoull() to convert the string to number, which will fail if the number is out range:
If the value read is out of the range of representable values by an unsigned long long int, the function returns ULLONG_MAX (defined in
<limits.h>), anderrnois set toERANGE.
Example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
char str[100]=;
fgets(str, sizeof(str), stdin);
str[strcspn(str, "\n")] = '\0';
if(strchr(str, '-') == NULL) {
printf("Not a negative number\n");
unsigned long long number = strtoull (str, NULL, 10);
printf("%llu\n", number);
} else {
printf("Negative number\n");
}
return 0;
}
Output:
Not a negative number
12343566
and for -12343566, it gives:
Negative number
- 71,951
- 46
- 188
- 305
You could read the input into a character array using fgets(), check if the first character is a character other than a digit and then use -ve symbolstrtoull() to convert it to unsigned long long.
char c, buff[100];
fgets(buff, sizeof(buff), stdin);
//sscanf(buff, "%*[ ]%c", &c);
sscanf(buff, "%s", buff);
//if( (c<'0' || c>'9') )
if(buff[0]<'0' || buff[0]>'9')
{
printf("\nNegative or invalid number!");
}
else
{
num=strtoull(buff, NULL, 10);
}
strtoull() will return ULLONG_MAX (defined in limits.h) and sets errno to ERANGE(to use these, errno.h header file must be included) if the value returned by it won't fit in an unsigned long long.
if(num==ULLONG_MAX && errno==ERANGE)
{
printf("\nOverflow");
}
The %*[ ] in the sscanf() is used to ignore the leading white spaces in the string.
The first non-space character is found and stored in c whose value is checked.
As explained here, sscanf(buff, "%s", buff); would trim the string buff on both sides to get rid of the spaces.
- 5,079
- 1
- 20
- 35