自己实现整数换字符串函数和字符串转整数函数

x33g5p2x  于2021-10-14 转载在 其他  
字(2.5k)|赞(0)|评价(0)|浏览(714)

对于整数转换为字符串,或者字符串转换为整数,可以直接使用库函数中提供的方法。如常用的字符串转换相关函数如下:

  • atof():将字符串转换为双精度浮点型值。
  • atoi():将字符串转换为整型值。
  • atol():将字符串转换为长整型值。
  • strtod():将字符串转换为双精度浮点型值,并报告不能被转换的所有剩余数字。
  • strtol():将字符串转换为长整值,并报告不能被转换的所有剩余数字。
  • strtoul():将字符串转换为无符号长整型值,并报告不能被转换的所有剩余数字。

对于单片机来说,库函数比较大,调用库函数比较浪费空间,有时候库函数提供的方法在代码中只调用了一次,这样的话对于资源比较宝贵的单片机来说,调用库函数的性价比太低了。那么能不能自己写一个方法将整数和字符串相互转化呢?当然是可以的。

首先来了解一下字符和数字的差别。数字1 和字符’1’从外观上看基本一模一样很难分辨,但是对于单片机来说,识别的都是十六进制代码。数字1的16进制代码是0x01,字符‘1’的十六进制代码是0x31,它俩之间的差值为0x30,而0x30在ASCII码表中刚好是字符’0’.所以数字和字符之间的关系可以用下面的表达式 '1' = 1 + '0' 来表达。字符1就等于数字1加字符0。当自己编写函数的时候,就可以通过这个关系进行转换。

下面看整数转字符串的函数:

void int2str(int n, char *str)
{
    char buf[10] = "";
    int i = 0;
    int len = 0;
    int temp = n < 0 ? -n: n;  // temp为n的绝对值
    if (str == NULL)
    {
        return;
    }
    while(temp)
    {
        buf[i++] = (temp % 10) + '0';  //把temp的每一位上的数存入buf
        temp = temp / 10;
    }
    len = n < 0 ? ++i: i;  //如果n是负数,则多需要一位来存储负号
    str[i] = 0;            //末尾是结束符0
    while(1)
    {
        i--;
        if (buf[len-i-1] ==0)
        {
            break;
        }
        str[i] = buf[len-i-1];  //把buf数组里的字符拷到字符串
    }
    if (i == 0 )
    {
        str[i] = '-';          //如果是负数,添加一个负号
    }

}

由于整数有正数和负数之分,负数输出的时候要在前面添加负号,所以首先将传递进来的整取绝对值。temp = n < 0 ? -n: n;这行代码意思就是如果是负数,就给负数在取一次负,然后赋值给temp。如果是正数就直接赋值给temp。相当于temp存储的就是绝对值数。

接下来依次将整数的每个位都转换为字符。比如数字1234,要转换为字符的话,首先对数字1234取余,取出余数4,然后给数字4加上字符’0’,这样数字4就转换成了字符’4’。将字符’4’存储在字符串中,接下来将数字1234除10取整,结果为123。也就是将转换字符成功的数字去掉,接来下按照上面的方法继续转换数字3。

当数字都转换为字符串之后,此时字符串中存储的应该是“4321”,倒叙排列,因为第一个转换的字符是’4’,最后一个转换的字符是’1’,所以顺序刚好和数字是反的。

接下来通过len = n < 0 ? ++i: i;这行语句来判断传递进来的数字是正数还是负数,如果是负数,就要给buf数组中增加一位,用于存储"-“号。所以就要给数组长度下标i加一,然后用0将增加的这一位填充。如果传递进来的是负数,那么打印的时候,就用”-"号将默认的0替换掉。

由于刚才转换后的字符串是数字倒叙排列,现在就需要将字符串反过来储存。从buf数组中最后一位取数据,存储到str数组中的第一位。这样依次将倒序的字符串正向存储在str字符串中。
最后判断如果是负数,则在str中最开始位置添加上“-”号。

接下来编写测试代码。

int i = -10
while( 1 )
{
       LED = ~LED;         
       delay_ms( 500 );     
       i++;
       int2str(i,s);
       printf("%d\r\n",i);
 }

定义一个整数i,然后每次循环递增1,然后通过整数转字符串函数将整数 i 转换为 字符串,然后打印出来。运行结果如下:

  通过打印结果可以看出,正数和负数的转换都是正确的。

整数转换字符串成功后,那么字符串转整数就更简单了,将上面的过程反过来执行就行了。

int str2int(const char *str)
{
    int temp = 0;
    const char *ptr = str;            //ptr保存str字符串开头
    if (*str == '-' || *str == '+')  //如果第一个字符是正负号,
    {                                //则移到下一个字符
        str++;
    }
    while(*str != 0)
    {
        if ((*str < '0') || (*str > '9'))  //如果当前字符不是数字
        {                                 //则退出循环
            break;
        }
        temp = temp * 10 + (*str - '0');  //如果当前字符是数字则计算数值
        str++;                           //移到下一个字符
    }   
    if (*ptr == '-')                    //如果字符串是以“-”开头,则转换成其相反数
    {
        temp = -temp;
    }
    return temp;
}

首先判断传递进来的字符串前面有没有正负号,如果有符号就取下一位字符,然后判断字符是否在 ‘0’到’9’之间,因为如果是字符不是数字的话,说明传递的是非法字符,就退出转换。如果字符合法,将当前字符减去字符’0’,结果就是字符对应的数字。然后将转换后的字符赋值给temp,然后再乘以10,就相当于将整数向前移动了一位。数字转换完成后,如果是负数,就给数字前面添加上负号,最后返回转换后的值。

接下来编写测试代码。

int i,j;
   char s1[10]="6789";
   char s2[10]="-2345";
    while( 1 )
    {
        LED = ~LED;         
       delay_ms( 500 );
       
       i = str2int(s1);
       j = str2int(s2);
       printf("i = %d,j = %d\r\n",i,j);
    }

定义了两个字符串,一个正数,一个负数,然后通过字符串转整数函数转换,最后将转换结果打印出来。运行结果如下:

  通过串口输出的结果可以看出,字符串转整数函数转换数据成功。

相关文章