Поскольку ваш return_val
является unsigned int
, вам, вероятно, следует использовать strtoul()
, который был стандартным с C89 и поэтому поддерживается MSVC (тогда как strtoll()
был стандартным только с C99 и не поддерживаетсяMSVC).
Ваше тестирование условий ошибки не подходит.Вам нужно установить errno
в ноль перед вызовом функции преобразования;Вам также необходимо определить, была ли сообщена ошибка, что сложнее, чем кажется.
Раздел §7.20.1.4 «Функции strtol, strtoll, strtoul и strtoull» стандарта C99 гласит:
Возвращает
Функции strtol
, strtoll
, strtoul
и strtoull
возвращают преобразованное значение, если оно есть.Если преобразование не может быть выполнено, возвращается ноль.Если правильное значение находится за пределами диапазона представимых значений, возвращается LONG_MIN, LONG_MAX, LLONG_MIN, LLONG_MAX, ULONG_MAX или ULLONG_MAX (в соответствии с типом возврата и знаком значения, если есть), а значение макроса ERANGE равнохранится в errno
.
. Вы также должны прочитать значение, сохраненное в параметре endptr
, в функции преобразования, чтобы сказать, что преобразование не было выполнено (в отличие от действительного нуля).был преобразован).
Если последовательность объекта пуста или не имеет ожидаемой формы, преобразование не выполняется;значение nptr
сохраняется в объекте, на который указывает endptr
, при условии, что endptr
не является нулевым указателем.
Итак, вы должны написать код, подобный этому (безпроверка на EINVAL, потому что в стандарте не упоминаются эти функции, устанавливающие errno
в EINVAL):
unsigned int return_val=0;
if (index + 1 <= argc - 1)
{
char *end;
unsigned long ul;
errno = 0;
ul = strtoul(argv[index+1], &end, 10);
if ((ul == 0 && end == argv[index+1]) ||
(ul == ULONG_MAX && errno == ERANGE) ||
(ul > UINT_MAX))
{
fprintf(stderr, "Could not parse argument %s for switch %s!\n",
argv[index], argv[index+1]);
return 0;
}
retval = (unsigned int)ul;
}
Обратите внимание, что это проще, чем проверка для целочисленного преобразования со знаком, который должен учитывать отрицательное значение <type>_MIN
limit, а также предел <type>_MAX
.
Также обратите внимание, что вы действительно должны записать результат в unsigned long
, а затем проверить, соответствует ли он вашему назначенному диапазону, который может быть ограничен UINT_MAX (которыйможет быть меньше, чем ULONG_MAX в Unix-подобной 64-битной среде).