I have the following
unsigned int value = 12;
int res = std::sscanf("-567", "%u", &value);
When this is run res is 1 indicating 1 match and value is set to 4294966729 Whereas I was expecting no matches to be made
I would be grateful if someone could explain this behaviour.
The C11 Standard states
"... whose format is the same as expected for the subject sequence of the strtoul
function with the value 10 for the base argument ..."
and, for strtoul
"... If the subject sequence begins with a minus sign, the value resulting from the conversion is negated ..."
#include <stdio.h>
int main(void) {
unsigned int value;
int res;
res = sscanf("-567", "%u", &value);
if (res == 1) {
printf("Value: %u\n", value);
} else {
fprintf(stderr, "Error\n");
}
res = sscanf("567", "%u", &value);
if (res == 1) {
value = ~value + 1; // add 1 in two's complement machines
printf("Value: %u\n", value);
} else {
fprintf(stderr, "Error\n");
}
return 0;
}
Given your usage of std::sscanf()
, you're actually using C++, not C. But C++'s sscanf()
behaves in largely the same way as in C.
The specification of the %u
format specifier allows a sign to be included. Which would essentially mean modulo arithmetic will be employed. Assuming a 32 unsigned int
type, the result will be modulo 4294967296
to produce a value between 0
and 4294967295
. -567
modulo 4294967296
(aka the smallest positive remainder obtained on dividing -567
by 4294967296
) is 4294966729
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With