我正在尝试制作一个无限计算器(数字大小大于或小于整数),只处理字符串。
我正在做加法,但是当我需要向下一个字符报告十时遇到问题:比如9+7=16,我将在当前字符中放入6,在结果字符串的下一个字符中放入1。
这是我的代码:

 char    *add_inf(char *nb1, char *nb2, char *rslt)
{
  if (*nb1 && *nb2)
    {
      *rslt = (*nb1 - '0' + *nb2 - '0' > 9 ? (*nb1 - '0' + *nb2 - '0') % 10 : *nb1 - '0' + *nb2 - '0') + *rslt - '0' + '0';
      if (*nb1 - '0' + *nb2 - '0' > 9)
        {
          rslt++;
          *rslt = '1'; //Here i put the next char to '1'
          add_inf(nb1 + 1, nb2 + 1, rslt);
        }
      add_inf(nb1 + 1, nb2 + 1, rslt + 1);
    }
  return (rslt);
}

很抱歉-'0'和+'0'搞砸了,我应该做一个函数将其子化并在计算之前添加它。
当输入为nb1=“11111111”和nb2=“58856557”时,输出正确:
69967668

但当我输入nb1=“11111114”和nb2=“588856557”时,输出是:
699676611

代替将1添加到下一个字符,并具有:
69967671

它只是将“1”字符添加到我的结果字符串中。
思想?

最佳答案

一。我给你看三行代码:

*rslt = (*nb1 - '0' + *nb2 - '0' > 9 ? (*nb1 - '0' + *nb2 - '0') % 10 : *nb1 - '0' + *nb2 - '0') + *rslt - '0' + '0';

*nb1 - '0' + *nb2 - '0' <= 9时,条件的真边和假边将具有相同的输出。因此,我们可以使用这一行糟糕的代码(需要实际的时间来解析),并将其重写为更清晰的代码:
*rslt = ((*nb1 - '0' + *nb2 - '0') % 10) + *rslt - '0' + '0';

我们还可以使用“+”操作符进一步清理它。
*rslt += (*nb1 - '0' + *nb2 - '0') % 10;

2。您的用户输入
不清楚如何调用这个函数。我假设rslt是一个'0'字符串,它至少比其他两个字符串长一个字节。
三。溢出
你没有正确检查溢出。让我们看一个简单的例子:"54" + "65"。在第一个循环中,您将正确存储1作为第一个结果。你将携带一个1到下一个迭代。
但是,在下一次迭代中,如果溢出,则不使用进位来测试。在这里,您的代码将显示lhs + rhs == 9,因此您很好。但实际上,这是lhs + rhs + carry == 10
四。克拉斯·林德巴克说的一切。
In this answer
5个。返回值
假设您总是希望返回值指向完整的rslt字符串。你的代码不会那么做。溢出时,会增加rslt的值。因此,如果前两个字符导致溢出,则返回值实际上是指向完整rslt字符串的第二个字符的指针。
6。因此…
所以如果我们把这些都放在心上,我们可以产生一些类似这样的代码。
char *add_inf(char *nb1, char *nb2, char *rslt) {
    if (*nb1 && *nb2) {
        int sum = (*nb1 - '0' + *nb2 - '0' + *rslt - '0');

        *(rslt + 0) = (sum % 10) + '0';
        if (sum / 10)
            *(rslt + 1) = (sum / 10) + '0';

        add_inf(nb1 + 1, nb2 + 1, rslt + 1);
    }

    return rslt;
}

int main() {
    char nb1[]    = "11111114";
    char nb2[]    = "58856557";
    char output[] = "000000000";

    add_inf(nb1, nb2, output);
    printf("%s\n", output);
}

得到了和你一样的答案!怎么回事?
好吧,你的代码假设最低有效位在左边,最高有效位在右边。所以在你的字符串中,如果你想把数字100和200相加,你实际上会做inf_add("001", "002");
如果这不是您想要的,那么您需要按相反的顺序迭代字符串!
7号。相反顺序的代码是什么样子的?
好吧,递归做有点烦人,所以我要用循环。
char *add_inf(char *nb1, char *nb2, char *rslt) {
    int len = strlen(nb1);
    int carry = 0;

    for (int i=len - 1; i >= 0; --i) {
        int sum = (nb1[i] - '0' + nb2[i] - '0' + carry);

        rslt[i] = (sum % 10) + '0';
        carry   = (sum / 10);
    }

    return rslt;
}

int main() {
    char nb1[]    = "11111114";
    char nb2[]    = "58856557";
    char output[] = "00000000";

    add_inf(nb1, nb2, output);
    printf("%s\n", output);
}

正如你可能希望的那样,这会产生:
69967671

请注意,在这段代码中,我们将字符串从字符串的末尾迭代到字符串的开头。
此外,在return之前,我们可以测试carry以查看它是否为非零。如果它是非零的,我们可以断言或者其他什么来通知用户加法溢出。

10-01 06:59