Search code examples
chexstrtoul

What does the 2nd argument in strtoul() function do?


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?


Solution

  • 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.