【题目】
给定一个字符串str,如果str符合日常书写的整数形式,并且属于32位整数的范围,返回str所代表的的整数值,否则返回0。
【举例】
str="123",返回123。
str="023",返回0。
【实现】
#include <iostream>
#include <string>
using namespace std;
bool isValid(string str)
{
if (str[0] == '-' && (str.size() == 1 || str[1] == '0'))
return false;
if (str[0] != '-' && (str[0]<'0' || str[0] >'9'))
return false;
if (str[0] == '0'&&str.size() > 1)
return false;
for (int i = 1; i < str.size(); i++)
{
if (str[i]<'0' || str[i]>'9')
{
return false;
}
}
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
string str;
getline(cin, str);
if (str == "" || str.size() < 1)
{
cout << 0;
return 0;
}
if (isValid)
{
cout << 0;
return 0;
}
int cur = 0, num = 0;
int minq = INT_MIN / 10;//-214748364
int minr = INT_MIN % 10;//-8
bool sym = str[0] == '-' ? false:true;
for (int i = sym? 0:1; i < str.size(); i++)
{
cur = '0'-str[i];
if ((num<minq)||(num==minq&&cur<minr))
{
cout << 0;
return 0;
}
else
{
num = num * 10 +cur;
}
}
if (sym&&num == INT_MIN)
{
cout << 0;
return 0;
}
cout << sym ? -num : num;
return 0;
}
【知识点】
1、首先对于字符串是否符合日常书写的整数形式检查,应该考虑到:
①当第一个字符为负号并且字符串长度等于1时,返回0;
②当第一个字符为负号并且第二个字符为0时,返回0;
③当第一个字符为0并且字符串长度大于1时,返回0。
④对第一个字符检查后,再从第二个字符一次检查是否在‘0’-‘9’内即可。
2、对于整数是否溢出的问题,这里使用了最小值对10求商和求余,方法值得借鉴。
3、int类型在32位和64位机中都占4个字节,即32位。那么可以表示的范围为-2的31次方~2的31次方-1;即-2147483648~2147483647,所以代码中统一使用负数进行转换,因为负数表示范围要比整数大1。
4、其实本实现和头文件#include <stdlib.h>中的atoi()是差不多的,其函数用来将字符串转换成整数(int),其原型为:
int atoi (const char * str);与此对应将整数转换为字符串的函数为itoa();itoa()函数有3个参数:第一个参数是要转换的数字,第二个参数是要写入转换结果的目标字符串,第三个参数是转移数字时所用的基数。