我试过
sscanf(str, "%016llX", &int64 );
但似乎不安全。是否有快速安全的方式进行类型转换?
感谢〜
答案 0 :(得分:7)
不要打扰scanf
系列中的功能。它们几乎不可能强有力地使用。以下是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 */
}
请注意,strtoull
在字符串上接受可选的0x
前缀,以及可选的初始空格和符号字符(+
或-
)。如果要拒绝这些,则应在调用strtoull
之前执行测试,例如:
if (!isxdigit(str[0]) || (str[1] && !isxdigit(str[1])))
如果您还希望禁止过长的数字表示(前导零),您可以在致电strtoull
之前检查以下条件:
if (str[0]=='0' && str[1])
要记住的另一件事是“负数”不被视为超出转换范围;相反,前缀-
的处理方式与C中应用于无符号值的一元否定运算符相同,因此例如strtoull("-2", 0, 16)
将返回ULLONG_MAX-1
(不设置errno
)。
答案 1 :(得分:2)
您的标题(目前)与您提供的代码相矛盾。如果你想做你的标题最初(将字符串转换为整数),那么你可以使用这个答案。
您可以使用strtoull
功能,与sscanf
不同,该功能专门用于阅读数字的文字表示。
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 :(得分:0)
当我写这个答案的时候,你的标题建议你想把一个uint64_t写成一个字符串,而你的代码则反其道而行(将一个十六进制字符串读入一个uint64_t)。我回答“两种方式”:
<inttypes.h>
标头有转换宏来安全处理..._t
类型:
#include <stdio.h>
#include <inttypes.h>
sprintf( str, "%016" PRIx64, uint64 );
或者(如果这确实是你想要做的事情),反之亦然:
#include <stdio.h>
#include <inttypes.h>
sscanf( str, "%" SCNx64, &uint64 );
请注意,您无法使用scanf()
函数系列强制执行宽度等。它解析它得到的东西,当输入不符合预期的格式时,会产生不希望的结果。哦,scanf()
函数族只知道(小写)“x”,而不是(大写)“X”。