Что делает 2-й аргумент в функции strtoul()?

#c #hex #strtoul

#c #шестнадцатеричный #strtoul

Вопрос:

Согласно этому документу,

Второй аргумент (char **endptr) кажется пустой тратой места! Если для него установлено значение NULL, STRTOL, похоже, продвигается вниз по строке, пока не найдет недопустимый символ, а затем останавливается. Затем преобразуются все прочитанные допустимые символы, если строка начинается с недопустимого символа, функция возвращает НОЛЬ (0).

Это означает, что следующий код должен определять 2 как шестнадцатеричное число:

 int main()
{
    char * string = "p1pp2ppp";

    unsigned integer = strtoul(string, NULL, 16);

    printf("%u", integer);

    return 0;
}
  

но он возвращает ноль.

Почему?

Комментарии:

1. Функция попытается проанализировать строку с начала . И поскольку первый символ не является шестнадцатеричной цифрой, он немедленно завершится ошибкой (как задокументировано ).

2. Что касается endptr аргумента, он разыменован, чтобы вернуть указатель на первый неразработанный символ в строке.

3. Вариантов использования может быть много. Чаще всего он используется для проверки, была ли проанализирована вся строка (например, "123" где конечный указатель будет на терминатор) или только начальная часть (например, для "123xyz" того, где конечный указатель будет на 'x' ).

4. Качество справочного материала можно определить по использованию фразы «кажется». Это означает, что автор действительно не имеет понятия.

5.С char *p; int i = strtoul("24-3", amp;p, 10); i будет 24 , p будет указывать на "-3" .

Ответ №1:

Страница руководства говорит следующее о втором аргументе:

Если значение endptr не равно NULL, strtol() сохраняет адрес первого недопустимого символа в *endptr. Если цифр вообще не было, strtol() сохраняет исходное значение nptr в *endptr (и возвращает 0). В частности, если *nptr не равен ‘ 0’, а **endptr равен » при возврате, вся строка является допустимой.

Например:

 char str[] = "123xyz45";
char *p;
long x = strtol(str, amp;p, 10);
printf("x=%ldn", x);
printf("p - str = %dn", p - str);
printf("*p = %cn", *p);
printf("p (as string) = %sn", p);
  

Вывод:

 x=123
p - str = 3
*p = x
p (as string) = xyz45
  

Мы можем видеть, что когда strtol возвращает p указывает на первый символ в str , который не может быть преобразован. Это можно использовать для разбора строки по частям за раз или для проверки того, можно ли преобразовать всю строку целиком или есть ли какие-то дополнительные символы.

В случае вашего примера первый символ в string , а именно «p», не является базовой цифрой 10, поэтому ничего не преобразуется, и функция возвращает 0.

Ответ №2:

Почему?

Он возвращается, 0 потому что "p..." не следует никаким правилам о целочисленном представлении. 2-й аргумент не имеет отношения к вашему вопросу.

Ответ №3:

char **endptr Аргумент во всех strto* функциях предназначен для получения адреса первого символа, который не является частью допустимого целого числа (десятичного, шестнадцатеричного или восьмеричного) или числа с плавающей запятой. Далеко не бесполезный, он удобен для проверки неверного ввода. Например, если я хотел ввести 1234 , но с толстыми пальцами что-то вроде 12w4 , strtoul вернет 12 и установит аргумент endptr, указывающий на w .

В принципе, если символ, на который endptr указывает символ, не является пробелом или 0 , то ввод, скорее всего, следует отклонить.