这两天做的一个项目需要将十进制字符串(只含'0'--'9' )转换成相应的数字。比如将“123456789”转换成数字123456789。要求只转换指定长度而不是转换到字符串的结束‘\0’。在网上搜到了比如StrToInt()等都是处理字符串到字符串结束而且不知道那些函数能不能判断溢出,比如对于32位机来说4294967295是无符号整型能表示的最大数,如果所给的字符串超出了上述范围函数能不能判断出来。一个很简单的方法是用 sscanf 函数或者atoi函数,如下:
char a[] = "4294967295";
unsigned int i;
sscanf(a, "%d", &i);// 或者 i = atoi(a);
printf("i = %u\n", i);
缺点就是如果要转换的字符串表示的数超出了范围sscanf函数会自动截断。也就是说如果字符串是“4294967296”,转换后i=0。而且转换前还需要把要转换的字符串赋给一个字符数组。优点是它可以转换小数等其他功能。当然可以改进,可以判断溢出,但判断不出非法字符:
// 将前面的'0'去掉
char p[] = "4294967295";
char *a = p;
while (*a == '0')
{
++a;
}
unsigned int maxUINT = 0xFFFFFFFF;
char b[11];
unsigned int result;
sprintf(b, "%u", maxUINT);
if (strcmp(a, b) > 0)
{
printf("溢出!\n");
}
else
{
sscanf(a, "%u", &result);
printf("result = %u\n", result);
}
一般情况下用sscanf足够了。为了玩,我另写了一个函数。虽然效率差了许多但还勉强过得去。我没有用sscanf和sprintf,下面是代码。参数len是要转换的字符个数。
unsigned int StrToDec(const char *str, int len)
{
while (*str == '0')
{
str++;
len--;
}
unsigned int maxUINT = 0xFFFFFFFF;
// 32位机integer最大能表示十位
if (len > 10)
{
printf("溢出!\n");
return 0;
}
unsigned int tmpResult = 0;
if (len < 10)
{
while (len-- > 0)
{
tmpResult *= 10;
if (*str >= '0' && *str <= '9')
{
tmpResult += (*str) - '0';
}
else
{
printf("字符串出现非法字符!\n");
return 0;
}
str++;
}
return tmpResult;
}
else
{
unsigned int tmpQuotient = 0;// 商
unsigned int tmpRemainder = 0;// 余数
if (*str >= '0' && *str <= '9')
{
tmpResult += (*str) - '0';
}
str++;
while (len-- > 1)
{
if (*str >= '0' && *str <= '9')
{
tmpQuotient = maxUINT / (unsigned int)pow(10, len);
tmpRemainder = maxUINT % (unsigned int)pow(10, len);
if ((tmpResult < tmpQuotient)
|| ((tmpResult == tmpQuotient)
&& (*str - '0' <= tmpRemainder / pow(10, len - 1))))
{
tmpResult *= 10;
tmpResult += (*str) - '0';
str++;
}
else
{
printf("溢出!\n");
return 0;
}
}
else
{
printf("字符串出现非法字符!\n");
return 0;
}
}
return tmpResult;
}
}
十进制字符串(只含'0'--'9' )的溢出判断有点复杂,十六进制字符串(含'0' -- '9'以及'a' -- 'f'或'A'--'F')的溢出判断就相对简单了:
unsigned int HexStrToDec(const char *str, int len)
{
// 32位机
if (len > 8)
{
return 0;
}
unsigned int tmpResult = 0;
while (len-- > 0)
{
tmpResult <<= 4;
if (*str >= '0' && *str <= '9')
{
tmpResult |= *str - '0';
}
else if(*str >= 'A' && *str <= 'F')
{
tmpResult |= *str - 'A' + 10;
}
else if(*str >= 'a' && *str <= 'f')
{
tmpResult |= *str - 'a' + 10;
}
str++;
}
return tmpResult;
}
//下面是我在网上找的一位大牛用C++实现的,方法很简便,缺点是处理大量数据转换速度较慢。用C++的stringstream:
#include <sstream>
#Include <string>
string num2str(double i)
{
stringstream ss;
ss << i;
return ss.str();
}
int str2num(string s)
{
int num;
stringstream ss(s);
ss >> num;
return num;
}
The End.
<pre name="code" class="cpp">