题目描述
输入一个由数字组成的字符串,把它转换成整数并输出。例如:输入字符串"123",输出整数123。
给定函数原型int StrToInt(const char *str) ,实现字符串转换成整数的功能,不能使用库函数atoi。
分析与解法
基本思路为:从左至右扫描字符串,把之前得到的数乘以10,然后加上当前字符所表示的数字。
然而,我们需要考虑以下几个问题:
- 输入为空指针时
- 数字前面的正负号
- 非法的字符
- 整形溢出
前三个问题很容易解决,这里主要考虑整形溢出的问题。一般来说,当发生溢出时,返回最大或最小的int值。我们先设置几个变量:
- sign 用来表示数字的正负
- n用来存放转化后的结果
- c用来表示当前的数字
为了判断给定的数字转换后是否超出int所能表示的最大值,我们比较n 和 MAX_INT / 10的大小 ,即:
- 若n > MAX_INT / 10, 那么说明在最后进行转换时,n * 10 必然大于 MAN_INT,所以此时直接返回MAX_INT
- 若n == MAX_INT / 10,那么比较最后一个数字c和MAX_INT % 10的大小,如果 c > MAX_INT % 10,则返回MAX_INT
完整代码如下:
int StrToInt(const char* str) { static const int MAX_INT = (int)((unsigned)~0 >> 1); static const int MIN_INT = -(int)((unsigned)~0 >> 1) - 1; unsigned int n = 0;
//判断是否输入为空 if (str == 0) { return 0; }
//处理空格 while (isspace(*str)) ++str;
//处理正负 int sign = 1; if (*str == '+' || *str == '-') { if (*str == '-') sign = -1; ++str; }
//确定是数字后才执行循环 while (isdigit(*str)) { //处理溢出 int c = *str - '0'; if (sign > 0 && (n > MAX_INT / 10 || (n == MAX_INT / 10 && c > MAX_INT % 10))) { n = MAX_INT; break; } else if (sign < 0 && (n >(unsigned)MIN_INT / 10 || (n == (unsigned)MIN_INT / 10 && c > (unsigned)MIN_INT % 10))) { n = MIN_INT; break; }
//把之前得到的数字乘以10,再加上当前字符表示的数字。 n = n * 10 + c; ++str; } return sign > 0 ? n : -n; } |
举一反三
- 实现string到double的转换