How to quickly and safely convert a hexadecimal string to an unsigned 64bit (uint64_t) integer?

I tried

sscanf(str, "%016llX", &int64 ); 

but it seems unsafe. Is there a quick and safe way to do type casting?

Thanks ~

+6
c type-conversion uint64
source share
3 answers

Don't worry about the functions in the scanf family. They are almost impossible to use sensibly. Here is the general safe use of strtoull :

 char *str, *end; unsigned long long result; errno = 0; result = strtoull(str, &end, 16); if (result == 0 && end == str) { /* str was not a number */ } else if (result == ULLONG_MAX && errno) { /* the value of str does not fit in unsigned long long */ } else if (*end) { /* str began with a number but has junk left over at the end */ } 

Note that strtoull accepts the optional 0x prefix in the string, as well as the optional leading spaces and sign ( + or - ). If you want to reject them, you must run the test before calling strtoull , for example:

 if (!isxdigit(str[0]) || (str[1] && !isxdigit(str[1]))) 

If you also want to prohibit too long representations of numbers (leading zeros), you can check the following condition before calling strtoull :

 if (str[0]=='0' && str[1]) 

Another thing to keep in mind is that "negative numbers" are not counted outside the conversion range; instead, the prefix - treated in the same way as the unary negation operator in C, applied to an unsigned value, therefore, for example, strtoull("-2", 0, 16) will return ULLONG_MAX-1 (without setting errno ).

+7
source share

Your name (currently) is contrary to the code you provided. If you want to do what was originally in your title (convert a string to an integer), you can use this answer.


You can use the strtoull function, which, unlike sscanf is a function specifically designed to read textual representations of numbers.

 const char *test = "123456789abcdef0"; errno = 0; unsigned long long result = strtoull(test, NULL, 16); if (errno == EINVAL) { // not a valid number } else if (errno == ERANGE) { // does not fit in an unsigned long long } 
+2
source share

At the time I wrote this answer, your name suggested you write int64_t in a string, while your code did the opposite (reading the hexadecimal string in int64_t). I answered "in both directions":

The header <inttypes.h> has conversion macros for the safe storage of types ..._t :

 #include <stdio.h> #include <inttypes.h> sprintf( str, "%016" PRIX64, int64 ); 

Or (if this is really what you are trying to do), vice versa:

 #include <stdio.h> #include <inttypes.h> sscanf( str, "%" SCNx64, &int64 ); 

Please note that you cannot apply width, etc. with the scanf() family of functions. He analyzes what he gets, which can lead to undesirable results when the input does not match the expected formatting. Oh, and the scanf() family of functions knows (lowercase) "x", not (uppercase) "X".

0
source share

All Articles