Reputation: 7330
I am getting long from user input (with fgets()
and converting to long with strtoul()
), but when testing it to convert into integer giving wrong result.
Declarations:
char buf[BUFSIZE];
unsigned char input[80];
int done = 0;
int i, val;
long valPrimary;
char *ptr;
Code:
// gets the max first 79 characters, whichever comes first
if (fgets(input, INPUTSIZE, stdin) != NULL) {
printf("Input ok\n");
} else {
printf("Input not ok\n");
return 0;
}
// get unsigned long from input
valPrimary = strtoul(input, &ptr, 10);
// Check if any character was converted
if (ptr == input) {
fprintf(stderr, "Can't convert string to number\n");
return 0;
}
if ((valPrimary == LONG_MAX || valPrimary == LONG_MIN) && errno== ERANGE) {
fprintf(stderr, "Number out of range for LONG\n");
return 0;
}
printf("valPrimary: %lu\n", valPrimary);
printf("Max Int: %i\n", INT_MAX);
printf("Min Int: %i\n", INT_MIN);
printf("Long size: %lu\n", sizeof(long));
// Check overflows and if long is convertable to int
if ( (valPrimary > INT_MAX) || (valPrimary < INT_MIN) ) {
fprintf(stderr, "Number out of range for INT\n");
return 0;
} else {
val = (int) valPrimary;
}
For example if I enter some a very big number, I am getting this kind of stdout:
valPrimary: 18446744073709551615
Max Int: 2147483647
But error message is not displayed and conversion still happens.
Upvotes: 1
Views: 1037
Reputation: 3859
Probably, what is happening is this:
valPrimary is declared as:
long valPrimary;
rather than:
unsigned long valPrimary
The decimal value 18446744073709551615
corresponds to hexadecimal value 0xffffffffffffffff
.
When this value is stored in a signed long, the first bit is the sign bit. In fact, 0xffffffffffffffff
in a signed long is equal to -1
.
Hece, the conversion is made, and -1
is returned, since INT_MAX > -1 > INT_MIN
Upvotes: 1
Reputation: 153447
Incorrect mixing of signed long
and strtoul()
. Use strtol()
. @Quentin
strtoul("18446744073709551615",...)
--> ULONG_MAX
and that converted to long
likely becomes -1
.
long valPrimary;
...
// valPrimary = strtoul(input, &ptr, 10);
valPrimary = strtol(input, &ptr, 10);
...
if ((valPrimary == LONG_MAX || valPrimary == LONG_MIN) && errno== ERANGE) {
fprintf(stderr, "Number out of range for LONG\n");
Upvotes: 1