参考资料
(2)《剑指offer》
题目分析
本题需要注意的有几个方面:
(1)检查输入参数,指针是否为NULL;
(2)去除字符串前面的空格
(3)处理正负符号
(4)数值部分计算要注意:第一个是处理溢出;第二个是处理字符串中出现非数字符号的情况
(5)整体的错误处理选择:如果函数正确执行,应该返回转换后的数字,所以,就不能使用return某个数字来表示某个错误,而应该定义一个全局的错误变量errno,并在出现不同错误的时候设置该变量。
关于处理溢出的方案:
由于单独处理正负号,所以数值计算的值number不应出现负值,当出现负值的时候说明发生了溢出,这时再根据前面的正负号判断是正溢出还是负溢出,如果是正溢出,则将该值赋为最大正数,在C++中是:std::numeric_limits<int>::max();如果是负溢出,则将该值赋值为最小负数即可。
最后,贴上我的代码,地址是:https://github.com/duqicauc/CodeInterview/blob/master/StrToInt.cpp
#include <iostream> #include <limits> using namespace std; //定义几个错误状态枚举 enum Status{kValid = 0,kNULL,kOVERFLOW,kCHAR}; int status = kValid; int strToInt(const char* str) { /* 空指针检查 */ if (str == NULL) { status = kNULL; return 0; } /* 处理字符串前面的几个空格 */ while(isspace(*str)) str++; /* 正负号处理 */ int flag = 1; if (*str == '-') { flag = -1; str++; } else if (*str == '+') str++; /* 数值操作 */ int number = 0; while(*str != '\0') { if (*str >= '0' && *str <= '9') { number = number * 10 + *str - '0'; /* 处理overflow,int类型的范围为[-2147483648,2147483647]*/ if (number < 0) { if(flag == 1) number = std::numeric_limits<int>::max(); else if (flag == -1) number = std::numeric_limits<int>::min(); status = kOVERFLOW; return number; } str++; } else { /* 处理字符串中的非数字字符,策略是返回无效字符串状态 */ status = kCHAR; break; } } return number * flag; } int main() { char str[80]; cout << "请输入字符串:" <<endl; cin.getline(str,80); int result = strToInt(str); switch(status){ case kValid: cout << "字符串" << str << "对应的整数是:" << result <<endl; break; case kNULL: cout << "空指针错误" <<endl; break; case kCHAR: cout << "输入的字符串中有非数字字符" <<endl; cout << result <<endl; break; case kOVERFLOW: cout << "输入的字符串对应的数字使得Int类型溢出" <<endl; cout << result <<endl; } return 0; }