Search code examples
cstringstrtol

strtol not working as expected


I am unable to convert a string to a long using strtol. Having a leading "." before the number in the string returns 0. Without the "." strtol returns 3456 as expected.

#include <stdio.h>                                                              
#include <stdlib.h>   

int main ()
{                                                                   
    char str[20] = " . 3456\r\n";                                                                    

    long ret = strtol(str, NULL, 10);                                            
    printf("ret is %ld\n",ret);

    return(0);                                                                   
}

Solution

  • The strto* library functions will only skip over leading whitespace. If you want to skip over other text, you need to do it by hand. The isxxx functions from ctype.h can help with this:

    #include <ctype.h>
    #include <errno.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    int main (int argc, char **argv)
    {
        char *p, *endp;
        unsigned long ret;
        int fail = 1;
    
        if (argc != 2) {
            fprintf(stderr, "usage: %s number-to-parse\n", argv[0]);
            return 2;
        }
        p = argv[1];
        while (*p && !isdigit(*p)) p++;
    
        errno = 0;
        ret = strtoul(p, &endp, 10);     
        if (endp == p)
            printf("'%s': no number found\n", str);
        else if (*endp && !isspace(*endp))
            printf("'%s': junk on line after number\n", str);
        else if (errno)
            printf("'%s': %s\n", str, strerror(errno));
        else {
            printf("'%s': parsed as %lu\n", str, ret);
            fail = 0;
        }
        return fail;
    }