【问题标题】:trying to make my code printout the correct product试图让我的代码打印出正确的产品
【发布时间】:2022-10-02 04:31:00
【问题描述】:

总和计算很好,但是,对于产品,使用的数字会创建一个大于 10 个整数的答案,这会给出错误的答案。我知道这是因为我使用的是 int。但是当我尝试浮动时,那也没有用。

有人可以解释如何使我的产品答案能够打印出大于 10 个整数的答案。

例如 6,20,4,16,15,11,6,3,19,18 的预期输出是 7800883200 但我的系统打印输出 72076004000

谢谢

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


int main(int argc, char* argv[]){
    
    if(argc<2){
        printf(\"Invalid Input: filename value missing\\n\");
    }
    else{
        char filename[50]; 
        strcpy(filename,argv[1]);
        FILE* fptr = fopen(filename,\"r\");
        
        if(fptr==NULL){
            printf(\"File not found!\\n\");
        }
        else{
            
            int arr[10]; 
            int i; 
            int val; 
            for(i=0;i<10;i++){
                fscanf(fptr,\"%d\",&val); 
                arr[i] = val;
            }

          
            int sum = 0; 
            
            for(i=0;i<10;i++){
                
                sum= sum + arr[i];
            }

            
           int product = 1;
            for(i=0;i<10;i++){
                product= product * arr[i]; 
            }

            printf(\"Sum: %d\\n\",sum);
            printf(\"Product: %d\\n\",product);
            fclose(fptr);
        }
    }
    return 0;
}
  • fopen 失败的原因有很多。您不应该假设这是因为找不到文件。让系统为你构造错误信息;将printf(\"File not found!\\n\"); 替换为perror(filename);
  • 如果输入与您的期望不符, fscanf() 可能会失败。始终检查返回值以查看您是否读取了预期的元素数量(在本例中为 1),否则 val 未定义。
  • 你忘了#include &lt;stdio.h&gt;
  • 出于好奇,您平台上的INT_MAX 是什么?如今,在大多数平台上,signed int 是 32 位的,这意味着它不能表示大于 2147483647 的值。
  • 7800883200 是一个 33 位的数字。

标签: c


【解决方案1】:

您需要使用具有足够范围的类型来存储您的product(和sum),因此不要使用int,而是使用long longdouble

缺少包含。使用strerror() 生成正确的错误消息。无需在打开文件之前复制文件名。您正在运行相同的循环 3 次,所以不妨将它们结合起来。这意味着您不再需要您的阵列。

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

int main(int argc, char* argv[]) {
    if(argc<2){
        printf("Invalid Input: filename value missing\n");
        return 1;
    }
    FILE *fptr = fopen(argv[1], "r");
    if(!fptr){
        printf("%s\n", strerror(errno));
        return 1;
    }
    long long sum = 0;
    long long product = 1;
    for(unsigned i=0; i<10; i++) {
        int val;
        fscanf(fptr,"%d",&val);
        sum += val;
        product *= val;
    }
    printf(
        "Sum: %lld\n"
        "Product: %lld\n",
        sum,
        product
    );
    fclose(fptr);
}
$ seq 10  | ./a.out /dev/stdin
Sum: 55
Product: 3628800

【讨论】:

  • 谢谢你。但是如何让它能够打印出更大的数字呢?
  • 使用更大的类型,double 或 long。
  • 错误消息属于 stderr,响应 fopen 的错误消息应包含使用的名称。代替printf("%s\n", strerror(errno));,使用fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));perror(argv[1]);。每次写入错误消息以响应包含用于打开文件的名称的fopen 故障时,小猫就会死亡。
  • 虽然这也是我第一次跳到的答案,但 OP 说他们实际得到的输出对于 32 位整数来说也太大了。奇特。
  • 我系统上的 INT_MAX 为 2 GiB,而操作员正在寻找的答案略低于 8 GiB。
【解决方案2】:

要打印更大的数字,但仍有不可避免的上限,请使用doubles 提供的附加位。

来自维基百科:

双精度(binary64),通常用来表示“双精度” 键入 C 语言家族。这是一种二进制格式,占用 64 位(8 字节),其有效位精度为 53 位 (大约 16 位十进制数字)。

这回答了你的“我怎么能?”您可以将这些知识整合到您的程序中。

#include <stdio.h>

int a[] = { 6,20,4,16,15,11,6,3,19, 18 };

int main() {
    double x = 1;

    for( int i = 0; i < 10; i++ ) {
        printf( "%.0lf * %d = %.0lf\n", x, a[i], x * a[i] );
        x = x * a[i];
    }

    return 0;
}

输出

1 * 6 = 6
6 * 20 = 120
120 * 4 = 480
480 * 16 = 7680
7680 * 15 = 115200
115200 * 11 = 1267200
1267200 * 6 = 7603200
7603200 * 3 = 22809600
22809600 * 19 = 433382400
433382400 * 18 = 7800883200 // <== your sought-after number

有可以使用的库任意算术可以与您的计算机一样大的值。

【讨论】:

    【解决方案3】:

    总和计算很好,但是,对于产品,使用的数字会创建一个大于 10 个整数的答案,这会给出一个不正确的答案。我知道这是因为我使用的是 int。但是当我尝试浮动时,那也没有用。

    int 变量的大小为 32 位宽,允许在 -2147483648+2147483647 之间存储数字,这会使您的产品溢出产生错误的答案。

    您可以尝试使用从-9223372036854775808+9223372036854775807long 整数,但可能对于大型产品,您也会溢出该变量。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-03-16
      • 1970-01-01
      • 2019-11-29
      • 2022-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多