将字符串转换成十进制数字

         这两天做的一个项目需要将十进制字符串(只含'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">
 
 
 
 
 
 
 
 
 
 
 

                
  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值