没想到写个strtol都这么难啊

经测试效率比apple版差一点点,我已经满足了。

static inline int
isspace(char c)
{
    return (c == ' ' || c == '\t' || c == '\n' || c == '\12');
}

static inline int
isupper(char c)
{
    return (c >= 'A' && c <= 'Z');
}

static inline int
islower(char c)
{
    return (c >= 'a' && c <= 'z');
}

static inline int
isdigit(char c)
{
    return (c >= '0' && c <= '9');
}

 

long int my_strtol(const char *nptr, char **endptr, int base)
{
    int neg = 0;
    const char *start = nptr; 
    errno = 0; 
    
    if (base < 0 || base == 1 || base > 36) {
        if (endptr) *endptr = nptr; 
        return 0; 
    }
    
    while (isspace(nptr[0])) {
        nptr++; 
    }
    
    if (nptr[0] == '-') {
        neg = 1; 
        nptr++;
    } else if (nptr[0] == '+') {
        nptr++; 
    }
    
    if ((base == 0 || base == 16) && nptr[0] == '0' && 
        (nptr[1] == 'x' || nptr[1] == 'X')) {
        nptr += 2; 
        base = 16; 
    } else if ((base == 0 || base == 2) && nptr[0] == '0'  && 
        (nptr[1] == 'b' || nptr[1] == 'B')) {
        nptr += 2; 
        base = 2; 
    } 
    
    
    if (base == 0) {
        base = nptr[0] == '0' ? 8 : 10; 
    }
    
    const char *start2 = nptr; 
    long int v = 0; 
    char c; 
    int erange = 0;
    while ( (c = *nptr) != '\0') {
        int d; 
        if (isdigit(c)) {
            d = c - '0';
        } else if (islower(c)) {
            d = c - 'a' + 10; 
        } else if (isupper(c)) {
            d = c - 'A' + 10; 
        } else {
            break; 
        }
        
        if (d >= base) {
            break; 
        }
        
        if (!erange) {
            long long v2 = ((long long)v) * base + (neg ? -d : d); 
            if (v2 > LONG_MAX) {
                v = LONG_MAX;
                errno = ERANGE;
                erange = 1;
            } else if (v2 < LONG_MIN) {
                v = LONG_MIN;
                errno = ERANGE; 
                erange = 1;
            } else {
                v = (long int)v2; 
            }
        }
        nptr++; 
    }
    
     if (endptr != NULL) *endptr = start2 == nptr ? start : nptr; 
     return v; 
}

 

 

posted @ 2012-10-22 01:39  lorddeseis  阅读(249)  评论(0编辑  收藏  举报