为什么该程序的结果始终为零?

时间:2020-10-02 11:52:22

标签: c

我正在尝试编写一个简单的程序,该程序最多可以接收30名学生的分数,姓名和ID,并平均打印分数。我想知道为什么程序的结果总是为零。
我很高兴有人能给我一个提示。
这是代码:

#include <stdio.h>

struct student{
    char name[30];
    int mark;
    int ID;

} s[30];

int main() {
    int n, i=0, sum=0;
    float average;
    /* printf("enter the number of students: "); */
    scanf("%d", &n);
    /* printf("enter their information: "); */

    for(i=0; i<n; i++)
        scanf("%s,%d,%d",s[i].name,&s[i].mark,&s[i].ID);

    for(i=0; i<n; i++)
         sum+=s[i].mark;
    
    average=sum/(float)n ;
    printf("%.2f", average);
}

4 个答案:

答案 0 :(得分:5)

格式说明符%s表示要读取一个字符串,并且正在这样做…包括逗号和后续字符。是“贪婪”。

然后%d就没有吸收的余地,因此所有整数都保持为零。

我建议您一次阅读一行,然后解析这些行。

或者,在this similar question上有一些建议。


遇到这样的问题时,您应该尝试通过检查调试器中的变量值来缩小范围,甚至只是通过使用printf来缩小范围,如下所示:

    printf("%s|%d|%d\n", s[i].name, s[i].mark, s[i].ID);

当我将其放在您的第一个循环中时,将以下输入传递给程序:

2
A,2,3
B,4,5

the output is this

A,2,3|0|0
B,4,5|0|0
0.00

...清楚表明解析是问题所在。

答案 1 :(得分:1)

问题出在这一行:

well done
Put your args data here

它将无法正常工作。为了测试它,我已经修改了您的程序。

scanf("%s,%d,%d",s[i].name,&s[i].mark,&s[i].ID);

https://godbolt.org/z/PredEd

您需要做什么?您需要使用int main() { int n = 10, i=0, sum=0; int scanfResult; float average; /* printf("enter the number of students: "); */ //scanf("%d", &n); /* printf("enter their information: "); */ for(i=0; i<n; i++) { scanfResult = scanf("%s,%d,%d",s[i].name,&s[i].mark,&s[i].ID); printf("scanf has scanned %d items\n", scanfResult); if(scanfResult != 3) { printf("you need to find another way of entering the data\n"); exit(1); } } for(i=0; i<n; i++) sum+=s[i].mark; average=sum/(float)n ; printf("%.2f", average); } 阅读鲸鱼行,并编写解析器以将此字符串分开

始终检查扫描结果

答案 2 :(得分:1)

如果您要输入带有空格的名称,例如

Joe Smith,90,1234

然后,问题是%s转换说明符停止在第一个空格字符处读取,因此它读取"Joe"并将"Smith"留在输入流中,从而阻塞了后两个读。另外,如果您没有空格,则%s会将整个输入行读入name(是否适合,可能导致缓冲区溢出)。

您应使用%[转换说明符而不是%s并显式调整其大小,以避免冒缓冲区溢出的风险。您还应该检查scanf的返回值,以确保您正确阅读了所有3项内容:

/**
 * loop until we have three good inputs;
 * %29[^,] reads up to 29 characters or to the next comma;
 * An array of size 30 can store a string of up to
 * 29 characters plus the string terminator;
 * Added leading blank in the format string to consume
 * any leading whitespace. 
 */
while ( scanf( " 29%[^,],%d,%d", s[i].name, &s[i].mark, &s[i].ID) != 3 )
{
   fprintf(stderr, "Bad input, try again\n" );
   /**
    * clear out the input stream before trying again
    */
   while ( getchar() != '\n' )
     ; // empty loop body
}

答案 3 :(得分:0)

您的问题是,中的scanf("%s,%d,%d",s[i].name,&s[i].mark,&s[i].ID);

我将代码更改如下:

scanf("%s%d%d",s[i].name,&s[i].mark,&s[i].ID);

然后输入和输出为: 输入:

2
moh 1 2
test 2 3

输出:

1.50