2015-11-15 64 views
-1

我正在尝试组合一个程序,这个程序总和非常大。不幸的是,我被卡住了 - 它不会返回任何结果,即使我注释掉了malloc & realloc(编译器似乎失败了)。有任何想法吗?我的代码:如何总结大数字

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int i,j,x; 
char *actual = NULL; 
char *sum = NULL; 

void init() { 
    sum = malloc(500); 
    actual = malloc(500); 
} 

void calculate (char *argv[]) { 
    int rest = 0; 
    actual = *argv; 
    actual = realloc(actual, strlen(*argv)); 
    if (strlen(actual) > strlen(sum)) { 
    sum = realloc(sum, strlen(actual) + 1); 
    } else sum = realloc(sum, strlen(sum) + 1); 
    long b; 
    for (b = 1; b < strlen(actual); b++) { 
     rest = rest + atoi(&sum[strlen(sum) - b]) + atoi(&actual[strlen(actual) - b]); 
     if (rest > 9) { 
      sum[strlen(sum) - b] = rest - 10; 
      rest = 1; // carrying over 1 
     } else { 
      sum[strlen(sum) - b] = rest; 
      rest = 0; 
     } 
    } 
} 

void writeResult() { 
    printf("VYPIS - sum:"); 
    printf("strlen souctu je: %lu\n",strlen(sum)); 
    long c; 
    for (c = 0; c <= strlen(sum); c++) { 
     printf("%c",sum[c]); 
    } 
    printf("\n"); 
} 

void emtpy() { 
    free(actual); 
    free(sum); 
} 

int main(int argc, char * argv[]) { 
    init(); 
    for (i = 1; i < argc; i++) { 
     calculate(&argv[i]); 
    } 
    writeResult(); 
    emtpy(); 
    return 0; 
} 
+0

经常检查可能会遇到错误函数的结果! – Olaf

+0

每次调用strlen()并确保传递一个有效的以NULL结尾的字符串。 –

+0

注意:'atoi'需要一个以null结束的字符串,这不是:'atoi(&sum [strlen(sum) - b])''。要转换一个数字,你可以做'x''0'。 – szczurcio

回答

0

你代码太复杂了,它有几个问题:

  • 您不能使用atoi将字符转换为v可以这样简单地完成:int value = c - '0'
  • 您不应该修改argv数组中的字符串。特别是你不能重新分配它们。这会调用未定义的行为。
  • 请务必分配或重新分配比您要存储在最终'\0'的结果数组中的字符串长度多一个字节,并记住设置该最终字节。
  • 你应该像从前一样计算从右到左的加法,跟踪从一位数到下一位数的进位,可能会增加一个额外的前导数字。

这里是你的问题更简化版本,显示了如何在基地10处理大量:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

static char *bigsum(char *res, const char *arg) { 
    size_t pos1, pos2, pos3, len3; 
    unsigned int carry; 

    pos1 = strlen(res); 
    pos2 = strlen(arg); 
    len3 = pos3 = (pos1 < pos2) ? pos2 + 1 : pos1 + 1; 
    /* reallocate the result array to one more than the larger operand */ 
    res = realloc(res, len3 + 1); 
    /* set the terminating '\0' at the end of result */ 
    res[pos3] = '\0'; 
    for (carry = 0; pos3 > 0; carry /= 10) { 
     if (pos1 > 0) carry += res[--pos1] - '0'; 
     if (pos2 > 0) carry += arg[--pos2] - '0'; 
     res[--pos3] = '0' + carry % 10; 
    } 
    while (res[0] == '0' && len3 > 1) { 
     /* normalize the result: remove redundant initial zeroes */ 
     memmove(res, res + 1, len3--); 
    } 
    return res; 
} 

int main(int argc, const char **argv) { 
    /* initialize the result to "0" as an allocated string */ 
    char *result = strcpy(malloc(2), "0"); 
    int i; 

    for (i = 1; i < argc; i++) { 
     result = bigsum(result, argv[i]); 
    } 
    printf("%s\n", result); 
    return 0; 
} 
+0

非常感谢,完美的作品! – gopi

2

试图reallocargv是不确定的行为。一般而言,您不应该使用realloc或从接收明确将内存所有权转移给您的函数。

另请注意,atoi需要以空字符结尾的C字符串,因此将它传递给长字符串的一部分是不正确的。如果你想获得一个char位的数值,减去'0',像这样:

int digit = actual[strlen(actual) - b] -'0'; 

为单个十进制数字数字转换为char,加'0'回:

res[b] = digit + '0'; 
+0

我怀疑OP认为'actual = * argv''复制char数组,(我们知道它不)。 –