Не беспокойтесь о функциях семейства 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
).