概述
第三十章、字符串转换成整数
先看题目:
输入一个表示整数的字符串,把该字符串转换成整数并输出,例如输入字符串"345",则输出整数345。
给定函数原型int StrToInt(const char *str) ,完成函数StrToInt,实现字符串转换成整数的功能,不得用库函数atoi(即便准许使用,其对于溢出情况的处理也达不到题目的要求,详情请参看下文第7节末)。
我们来一步一步分析(共9小节,重点在下文第8小节及后续内容),直至写出第一份准确的代码:
1、本题考查的实际上就是字符串转换成整数的问题,或者说是要你自行实现atoi函数。那如何实现把表示整数的字符串正确地转换成整数呢?以"345"作为例子:
- 当我们扫描到字符串的第一个字符'3'时,由于我们知道这是第一位,所以得到数字3。
- 当扫描到第二个数字'4'时,而之前我们知道前面有一个3,所以便在后面加上一个数字4,那前面的3相当于30,因此得到数字:3*10+4=34。
- 继续扫描到字符'5','5'的前面已经有了34,由于前面的34相当于340,加上后面扫描到的5,最终得到的数是:34*10+5=345。
因此,此题的思路便是:每扫描到一个字符,我们便把在之前得到的数字乘以10,然后再加上当前字符表示的数字。
2、思路有了,有一些细节需要注意,如zhedahht所说:
- “由于整数可能不仅仅之含有数字,还有可能以'+'或者'-'开头,表示整数的正负。因此我们需要把这个字符串的第一个字符做特殊处理。如果第一个字符是'+'号,则不需要做任何操作;如果第一个字符是'-'号,则表明这个整数是个负数,在最后的时候我们要把得到的数值变成负数。
- 接着我们试着处理非法输入。由于输入的是指针,在使用指针之前,我们要做的第一件是判断这个指针是不是为空。如果试着去访问空指针,将不可避免地导致程序崩溃。
- 另外,输入的字符串中可能含有不是数字的字符。每当碰到这些非法的字符,我们就没有必要再继续转换。
- 最后一个需要考虑的问题是溢出问题。由于输入的数字是以字符串的形式输入,因此有可能输入一个很大的数字转换之后会超过能够表示的最大的整数而溢出。”
比如,当给的字符串是如左边图片所示的时候,有考虑到么?当然,它们各自对应的正确输出如右边图片所示(
假定你是在32位系统下,且编译环境是VS2008以上):
3、很快,可能你就会写下如下代码:
- //copyright@zhedahht 2007
- enum Status {kValid = 0, kInvalid};
- int g_nStatus = kValid;
- // Convert a string into an integer
- int StrToInt(const char* str)
- {
- g_nStatus = kInvalid;
- long long num = 0;
- if(str != NULL)
- {
- const char* digit = str;
- // the first char in the string maybe '+' or '-'
- bool minus = false;
- if(*digit == '+')
- digit ++;
- else if(*digit == '-')
- {
- digit ++;
- minus = true;
- }
- // the remaining chars in the string
- while(*digit != '