使用结构数组的学生信息数据库(C语言)
函数computeScore()用于使用结构数组创建最多50名学生的数据库。该函数接收学生姓名、考试成绩和考试成绩,计算总成绩,然后打印出来。当学生姓名为“end”时,输入将结束。之后,程序将计算所有学生的总平均分数并打印出来 当我输入第一个学生的信息时,它工作正常,但是当程序第二次进入while循环时(当我想输入第二个学生的信息时),我遇到了麻烦 以下是我到目前为止所做的:使用结构数组的学生信息数据库(C语言),c,arrays,structure,C,Arrays,Structure,函数computeScore()用于使用结构数组创建最多50名学生的数据库。该函数接收学生姓名、考试成绩和考试成绩,计算总成绩,然后打印出来。当学生姓名为“end”时,输入将结束。之后,程序将计算所有学生的总平均分数并打印出来 当我输入第一个学生的信息时,它工作正常,但是当程序第二次进入while循环时(当我想输入第二个学生的信息时),我遇到了麻烦 以下是我到目前为止所做的: #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #i
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <math.h>
struct student{
char name[20]; /* student name */
double testScore; /* test score */
double examScore; /* exam score */
double total; /* total score = test+exam scores */
};
void computeScore();
int main()
{
computeScore();
return 0;
}
void computeScore()
{
struct student info[50];
int count = 1;
double allStudent = 0, allStudentAvg;
while (info[count].name != 'END')
{
printf("\nEnter student name: ");
gets(info[count].name);
printf("Enter test score: ");
scanf("%lf", &info[count].testScore);
printf("Enter exam score: ");
scanf("%lf", &info[count].examScore);
info[count].total = (info[count].testScore + info[count].examScore) / 2;
printf("Student %s's total= %f\n", info[count].name, info[count].total);
allStudent += info[count].total;
count++;
}
allStudentAvg = allStudent / count;
printf("Overall average = %f", allStudentAvg);
}
我得到的结果是:
Enter student name: John Doe
Enter test score: 34
Enter exam score: 46
Student John Doe's total = 40.000000
Enter student name: Enter test score:
\\Program skipped the input of 2nd student name
这是因为上次调用了
scanf
,它使换行符仍保留在缓冲区中,因此下一个获取
读取该换行符
您可以通过伪gets
调用显式获取该换行符,但通过在格式后添加空格,更容易告诉scanf
读取(并丢弃)尾随空格:
scanf("%lf ", &info[count].examScore);
/* ^ */
/* | */
/* Note space here */
不要担心前导空格(比如前一个
scanf
调用中留下的换行符),因为数字格式(以及其他一些格式)会自动跳过前导空格。您可能需要读取。这是因为上次调用了scanf
,它使换行符仍保留在缓冲区中,因此下一个获取
读取该换行符
您可以通过伪gets
调用显式获取该换行符,但通过在格式后添加空格,更容易告诉scanf
读取(并丢弃)尾随空格:
scanf("%lf ", &info[count].examScore);
/* ^ */
/* | */
/* Note space here */
不要担心前导空格(比如前一个
scanf
调用中留下的换行符),因为数字格式(以及其他一些格式)会自动跳过前导空格。您可能需要阅读。Scanf导致您出现此问题
在扫描前使用\uu fpurge(stdin)
解决您的问题
使用
fgets
而不是scanf
scanf会导致此问题
在扫描前使用\uu fpurge(stdin)
解决您的问题
使用
fgets
代替scanf不要使用get
读取字符串。这是一种痛苦!最好使用fgets
fgets(info[count].name, 20, stdin);
与scanf
一起使用时要小心。在这种情况下,这些函数读取上一次scanf
调用留下的\n
字符。
您可以通过在上次scanf
之后放置getchar
来使用此\n
scanf("%lf", &info[count].examScore);
getchar();
甚至更好
scanf("%lf", &info[count].examScore);
while(getchar() != '\n');
不要使用get
读取字符串。这是一种痛苦!最好使用fgets
fgets(info[count].name, 20, stdin);
与scanf
一起使用时要小心。在这种情况下,这些函数读取上一次scanf
调用留下的\n
字符。
您可以通过在上次scanf
之后放置getchar
来使用此\n
scanf("%lf", &info[count].examScore);
getchar();
甚至更好
scanf("%lf", &info[count].examScore);
while(getchar() != '\n');
预测您的下一个问题:
替换
info[count].name != 'END'
借
不能将字符串与进行比较=代码>操作员,您必须使用strcmp
功能
此外:
您声明int count=1
但这意味着info
数组的第一个元素将不被使用,您应该使用int count=0代码>
在while条件下info[count].name!='结束“
,info[count]。name
未初始化,因此您的比较可能总是错误的,即使您按照前面的建议使用strcmp
更正了条件。换句话说:您可以比较用户在输入“结束”之前是否输入了“结束”。预测您的下一个问题:
替换
info[count].name != 'END'
借
不能将字符串与进行比较=代码>操作员,您必须使用strcmp
功能
此外:
您声明int count=1
但这意味着info
数组的第一个元素将不被使用,您应该使用int count=0代码>
在while条件下info[count].name!='结束“
,info[count]。name
未初始化,因此您的比较可能总是错误的,即使您按照前面的建议使用strcmp
更正了条件。换句话说:您可以比较用户是否在输入“END”之前输入了“END”。对不起,我还不能评论。除了haccks的答案,我建议您在scanf之前使用fflush(stdin)或fluahall(),并且您应该使用strcmp代替信息[count]。name!='结束。很抱歉,我还不能发表评论。除了haccks的回答之外,我还建议您在scanf之前使用fflush(stdin)或fluahall(),并且您应该使用strcmp代替信息[count]。name!='结束。不要使用get
读取字符串。这是不安全的,因为如果输入字符串太大,调用未定义的行为,并且很可能由于segfault导致程序崩溃,它将溢出它写入的缓冲区。问题是while
循环中的最后一个scanf
调用在stdin
缓冲区中留下了尾随的换行符-
scanf("%lf", &info[count].examScore);
然后,在循环的下一次迭代中,gets
读取该换行符,导致gets
返回。阅读此C-FAQ,您应该使用scanf
而不是get
替换以下语句
gets(info[count].name);
借
请注意格式字符串“%19s”
中的前导空格。这会导致scanf
读取并丢弃stdin
缓冲区中任何数量的无关(包括零)空白字符19
表示scanf
将最多向缓冲区写入19个字符,然后在结尾追加空字节。这称为最大字段宽度并确保