我正在尝试编写一个简单的程序,该程序最多可以接收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);
}
答案 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
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);
您需要做什么?您需要使用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