-1

According to this document,

The second argument (char **endptr) seems to be a waste of space! If it is set to NULL, STRTOL seems to work its way down the string until it finds an invalid character and then stops. All valid chars read are then converted if the string starts with an invalid character the function returns ZERO (0).

It means that the following code should detect 2 as the hex number:

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

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

    printf("%u", integer);

    return 0;
}

but, it is returning zero.

Why?

user366312
  • 16,949
  • 65
  • 235
  • 452
  • 1
    The function will attempt to parse the string from the *beginning*. And since the first character is not a hexadecimal digit it will fail immediately (as [documented](https://en.cppreference.com/w/c/string/byte/strtoul)). – Some programmer dude Apr 08 '19 at 12:11
  • I'd recommend to read the "official" documentation as well: http://port70.net/~nsz/c/c11/n1570.html#7.22.1.4 – alk Apr 08 '19 at 12:12
  • well, that document is wrong. If endptr is passed, its is set to pointer of the first character after le last digit parsed and often that's very useful – Ingo Leonhardt Apr 08 '19 at 12:12
  • 2
    As for the `endptr` argument, it's dereferenced to give back a pointer to the first unparsed character in the string. – Some programmer dude Apr 08 '19 at 12:12
  • @Someprogrammerdude, *it's dereferenced to give back a pointer to the first unparsed character in the string.* - what is its usefulness? – user366312 Apr 08 '19 at 12:13
  • 1
    There could be many use-cases. Most often it's used to check if *all* of the string was parsed (for example `"123"` where the end pointer would be to the terminator) or only the beginning part (like for `"123xyz"` where the end pointer would be to the `'x'`). – Some programmer dude Apr 08 '19 at 12:14
  • 2
    The quality of the reference material can be determined from its use of the phrase "seems to". It means the author really doesn't have a clue. – Ian Abbott Apr 08 '19 at 12:15
  • 1
    With `char *p; int i = strtoul("24-3", &p, 10);` `i` will be `24`, `p` will point to `"-3"`. – pmg Apr 08 '19 at 12:15
  • That document looks like someone's personal notebook (and HTML practice). It hasn't been updated sice 1998, and is frequently very, very wrong or obsolete. – molbdnilo Apr 08 '19 at 12:28
  • Learning C: Rule 1 -> read the documentation. Rule 2 -> don't use crappy documentation. – Mark Benningfield Apr 08 '19 at 12:29

3 Answers3

1

The man page says the following about the second argument:

If endptr is not NULL, strtol() stores the address of the first invalid character in *endptr. If there were no digits at all, strtol() stores the original value of nptr in *endptr (and returns 0). In particular, if *nptr is not '\0' but **endptr is '\0' on return, the entire string is valid.

For example:

char str[] = "123xyz45";
char *p;
long x = strtol(str, &p, 10);
printf("x=%ld\n", x);
printf("p - str = %d\n", p - str);
printf("*p = %c\n", *p);
printf("p (as string) = %s\n", p);

Output:

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

We can see that when strtol returns p points to the first character in str that cannot be converted. This can be used to parse through the string a bit at a time, or to see if the entire string can be converted or if there are some extra characters.

In the case of your example, the first character in string, namely "p" is not a base 10 digit so nothing gets converted and the function returns 0.

dbush
  • 205,898
  • 23
  • 218
  • 273
0

Why?

It's returning 0 because "p..." does not follow any rules about integer representation. The 2nd argument is not relevant for your question.

pmg
  • 106,608
  • 13
  • 126
  • 198
0

The char **endptr argument in all the strto* functions is intended to receive the address of the first character that isn’t part of a valid integer (decimal, hex, or octal) or floating point number. Far from useless, it’s handy for checking invalid input. For example, if I meant to type in 1234 but fat-fingered something like 12w4, strtoul will return 12 and set the endptr argument to point to w.

Basically, if the character endptr points to isn’t whitespace or 0, then the input should most likely be rejected.

John Bode
  • 119,563
  • 19
  • 122
  • 198