【问题标题】:Error in the program that's give additional output提供额外输出的程序错误
【发布时间】:2022-11-25 21:51:23
【问题描述】:
#include <stdio.h>
#include <math.h>

int main()
{
    int i;
    int j;
    int base;
    int height;
    int side;
    int up;
    int down;
    int output[1001];
    
    for (i = 0; i < 1000; i++)
    {
        char type = getchar();
        
        if(type == 'P')
        {
            scanf("%d", &side);
            
            output[i] = side * side;
        }
        else if (type == 'S')
        {
            scanf("%d %d", &base, &height);
            
            output[i] = 0.5 * base * height;
        }
        else if (type == 'T')
        {
            scanf("%d %d %d", &up, &down, &height);
            
            output[i] = height * (up + down) / 2;
        }
        else if(type == '0')
        {
            break;
        }
    }
    
    for(j = 0; j < i; j++)
    {
        {
            printf("%d\n", output[j]);
        }
    }
    
    return 0;
}

我想要的是在我输入“0”之后, 该程序停止询问输入接着给出输出.总的来说它的工作,但有一个错误,在每个输出中,总是有 1 行“0”。

示例输入:

P 5
S 10 10
T 10 10 10
0

我想要的输出:

25
50
100

我现在使用此代码的输出:

25
0
50
0
100
0

我猜这是

else if(type == '0')
        {
            break;
        }

犯了这个错误,但我不确定,我不知道如何解决这个问题

【问题讨论】:

  • 您是否尝试过在调试器中逐行运行代码,同时监视控制流和所有变量的值,以确定您的程序在哪一行停止按预期运行?如果你没有尝试过这个,那么你可能想读这个:What is a debugger and how can it help me diagnose problems?你可能还想读这个:How to debug small programs?
  • 旁注:我建议您使用 switch 语句,而不是在同一变量上使用 if...else if 链。但是,这不是您遇到问题的原因。

标签: c


【解决方案1】:

问题是线条

scanf("%d", &side);
scanf("%d %d", &base, &height);
scanf("%d %d %d", &up, &down, &height);

will not extract the newline character at the end of the line

因此,在下一次循环迭代中,对getchar 的调用将提取该换行符,而对scanf 的调用将失败,因为下一个字符是整数。这意味着只有稍后调用 getchar 一个循环迭代才会实际提​​取新行的第一个字符。

通过在 debugger 中逐行运行您的程序,应该可以清楚地看到此错误,因为调试器将向您显示 type 的值在第二次循环迭代中将为 (ASCII 代码 10)。

要修复此错误,最简单的解决方案是在每次调用 scanf 之后添加对 getchar 的调用。

一个更健壮的解决方案不会使用scanf,而是使用函数fgets来读取一行输入,并使用sscanf来解析输入。

【讨论】:

    【解决方案2】:

    输入可以更好地可视化为:

    P 5
    
    S 10 10
    
    T 10 10 10
    
    0
    
    

    i 遇到的每个换行符都会增加一个额外的时间一个孤独的零。

    非常快速的解决方法是在向数组添加内容时仅增加 i

    for (i = 0; i < 1000;)
    {    
        char type = getchar();    
    
        if(type == 'P')    
        {    
            scanf("%d", &side);    
    
            output[i++] = side * side;    
        }    
        else if (type == 'S')    
        {    
            scanf("%d %d", &base, &height);    
    
            output[i++] = 0.5 * base * height;    
        }    
        else if (type == 'T')    
        {    
            scanf("%d %d %d", &up, &down, &height);    
    
            output[i++] = height * (up + down) / 2;    
        }    
        else if(type == '0')    
        {    
            break;    
        }    
    }
    

    这样还是会出现当EOFgetchar返回时无限循环的问题,并且不检查scanf的返回值是否成功执行了预期次数的调用转换让您可以对不确定的值进行操作。

    稍微重构一下:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define MAX 1001
    
    int get_int(void)
    {
        int x;
    
        if (1 != scanf("%d", &x))
            exit(EXIT_FAILURE);
    
        return x;
    }
    
    int main(void)
    {
        int i = 0;
        int output[MAX];
    
        while (i < MAX) {
            int type = getchar();
    
            if (EOF == type || '0' == type)
                break;
    
            int value;
            int up, down, height, side;
    
            switch (type) {
                case 'P':
                    side = get_int();
                    value = side * side;
                    break;
                case 'S':
                    value = 0.5 * get_int() * get_int();
                    break;
                case 'T':
                    up = get_int();
                    down = get_int();
                    height = get_int();
                    value = height * (up + down) / 2;
                    break;
                default:
                    continue;
            }
    
            output[i++] = value;
        }
    
        for (int j = 0; j < i; j++) {
            printf("%d
    ", output[j]);
        }
    }
    

    【讨论】:

    • 感谢您的解释和提示。
    猜你喜欢
    • 1970-01-01
    • 2015-10-17
    • 2017-05-18
    • 1970-01-01
    • 1970-01-01
    • 2018-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多