7

我试过

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

但似乎不安全。有没有一种快速安全的方法来进行类型转换?

谢谢~

4

3 回答 3

10

不要打扰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])

还要记住的一件事是“负数”不被视为超出转换范围;相反,前缀 of-被视为与 C 中应用于无符号值的一元否定运算符相同,因此例如strtoull("-2", 0, 16)将返回ULLONG_MAX-1(不设置errno)。

于 2010-11-09T10:59:15.080 回答
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
}
于 2010-11-09T10:00:20.013 回答
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”。

于 2010-11-09T10:02:08.500 回答