0

在广泛搜索将整数转换为视觉等效字符串的函数但一无所获之后,我决定编写自己的。

函数“ascii”接受三个参数:要转换的整数、保存转换后的整数的字符串和一个保留为 0 的计数器。

void ascii(int c, char str[], int k) {
    if (c <= 9) {
        str[k] = c + '0';
    }

    else if (c >= 10) {
        str[k] = c / 10 + '0';
        ascii(c % 10, str, k + 1);
    }
}

用个位数的数字测试这个函数并没有什么意外的结果,但是在更大的数字上,事情开始变得一团糟。76变成“761”,765变成“|51”,7658变成“-81”。数字包含的数字越多,我对结果字符串的理解就越少。是什么赋予了?

4

4 回答 4

3

我相信这是问题所在:

else if (c >= 10) {
    str[k] = c % 10 + 48;
    ascii(c / 10, str, k + 1);
}

算术运算被反转。之后必须反转生成的数组(来自不同的函数,该函数将问题中的函数作为助手调用),并且它必须以'\0'char 结尾。

或者,您可以以相反的顺序将结果复制到输出数组中,但前提是您事先知道位数。

于 2012-12-26T02:26:58.973 回答
1

对于这种情况c = 123,您实际上是在这样做:

    str[k] = 12 + '0';
    ascii(3, str, k + 1);

我不确定你打算发生什么,但这可能不是你的意思。

于 2012-12-26T02:28:13.127 回答
0
  • 首先你交换了模数和除法,这就是你得到那些意想不到的答案的原因。
  • 此外,这给出了您所期望的相反答案。所以修改数字然后尝试解决它。

    void ascii(int c, char str[], int k) {
    /*first let us reverse the string
    because recursive solution will be reverse of our expected solution*/
    int r=0,i;
    for(i=c;i>0;i=i/10)
    r=r*10+i%10;
    
    if (r <= 9) {
        str[k] = r + '0';
    
    }
    else if (r >= 10) {
         ascii(r / 10, str, k+1 );
         str[k] = r%10 + '0';
    }
    return;
    }
    
于 2012-12-26T09:31:42.810 回答
0

其他答案指出了最重要的错误-您交换了模数和除法;尽管如此,即使进行了更正,产生的字符串也会被反转,因为使用模数你很快就会得到最低有效位,它应该向右,但是你把它放在左边,因为一开始是未知的最终长度字符串。

您可以反转此字符串,使用对数查找位数或使用替代递归方法:

void ascii(int c, char str[])
{
    if(c<0)
    {
        *(str++)='-';
        c=-c;
    }
    *(ascii_helper(c, str))='\0';
}

char * ascii_helper(int c, char str[])
{
    if (c > 9)
        str=ascii_helper(c/10, str);
    *str = c%10 + '0';
    return str+1;
}

这是通过推迟数字的实际写入直到它们的位置已知来实现的。递归一直持续到找到最高有效数字为止,然后每个调用将下一个字符的位置返回给其调用者,该位置用于正确定位每个数字。请注意,此函数不能像原始函数那样进行尾部优化,因此它的空间效率较低(尽管这几乎无关紧要,因为ints 通常不能容纳超过 20 位数字)。

于 2012-12-26T02:42:28.793 回答