本方法借鉴自glibc,可以过滤如下情况:
前缀空格
非法输入
正负号
16进制8进制
溢出
1234L
#include <iostream> using namespace std; #define LONG_MAX 2147483647L #define LONG_MIN -2147483648L long StrToInt(const string &str){ unsigned long result = 0;//如果不用unsigned long,那么后面无法判断溢出(当发生溢出时,总是负数) int radix = 0; int sign = 1; string::const_iterator it = str.begin(); //1 filter preceding blank while (*it == ' ' || *it == '\t') it++; //2 judge sign if (*it == '+'){ sign = 1; it++; } else if (*it == '-'){ sign = 0; it++; } //3 judge invalid input on first char if (*it < '0' || *it > '9'){ cout<<"err input!"<<endl; return 0; } //4 judge radix radix = 10; if (*it == '0' && it+1 != str.end()){ it++; if (*it == 'x' || *it == 'X'){ it++; radix = 16; } else radix = 8; } //5 proceed each char one time while (it != str.end()){ unsigned long digit = *it - '0'; //5.1 invalid input if (*it < '0' || *it > '9'){ //5.2 long excludes, ex: 1234L if ((*it=='l'||*it=='L')&&(it+1==str.end())) break; else{ cout<<"err input!"<<endl; return 0; } } //5.3 overflow if (result > LONG_MAX/10 || sign>0 ? (result == LONG_MAX/10) && (digit < LONG_MAX%10) : (result == (LONG_MAX+1)/10) && (digit < (LONG_MAX+1)%10)){ cout<<"overflow!"<<endl; if (sign) result = LONG_MAX; else result = LONG_MIN; return result; } result *= radix; result += digit; it++; } //6 add sign if (sign == 0) result = 0 - result; return result; } int main() { string strs[10]; strs[0] = "123"; strs[1] = "0"; strs[2] = "abc"; strs[3] = "!#$%"; strs[4] = "0x5"; strs[5] = "-5L"; strs[6] = "-0x999999"; strs[7] = "-099999"; strs[8] = "1234%&s"; strs[9] = "-0x81had"; for (int i = 0; i < 10; i++){ long tmp = 0; cout<<StrToInt(strs[i])<<endl; } return 0; }
EOF