I have a file containing Strings representing float and uint64_t values.
I know exactly which string contains float values and which contains uint64_t values- that is not the problem I’m facing.
Here is how I convert them to their respective data-type:
char* t, v;
uint64_t cn;
cn = strtoull(t, &v, 10);
char* tt, vv;
float cn2;
cn2 = strtof(tt, vv);
But the problem arises at the following edge-case I want to catch:
let’s say the String for the uint64_t is "99999999999999999999999999999999999999999999999999"
This can’t be represented within 8 Bytes and therefore causes an overflow resulting in cn = 18446744073709551615.
Same problem with the float cn2.
How can catch this behavior? Thank’s!
>Solution :
strtoull provides an indication that the value is out of range but does not provide an unambiguous indication that it is too big, per C 2018 7.22.1.4 8. Consider this code:
#include <errno.h>
…
errno = 0; // Set error code to zero before call.
unsigned long long x = strtoull(t, &v, 10);
if (errno == ERANGE)
{
// Handle out-of-range error.
}
This will reach the error case if the numeral in t is too large. But it will also reach the error case if the numeral in t is negative. If you want to distinguish the too-large case particularly, you must examine the string to see if it contains a minus sign, possibly after initial spaces.
In contrast, strtof does provide sufficient information to distinguish cases, per C 2018 7.22.1.3 10:
- If the value is positive and too large,
HUGE_VALFis returned anderrnois set toERANGE. - If the value is negative and too large,
-HUGE_VALFis returned anderrnois set toERANGE. - If the value underflows the normal range, a small value is returned and
errnois set toERANGE.