没想到写个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; }