Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用结构数组的学生信息数据库(C语言)_C_Arrays_Structure - Fatal编程技术网

使用结构数组的学生信息数据库(C语言)

使用结构数组的学生信息数据库(C语言),c,arrays,structure,C,Arrays,Structure,函数computeScore()用于使用结构数组创建最多50名学生的数据库。该函数接收学生姓名、考试成绩和考试成绩,计算总成绩,然后打印出来。当学生姓名为“end”时,输入将结束。之后,程序将计算所有学生的总平均分数并打印出来 当我输入第一个学生的信息时,它工作正常,但是当程序第二次进入while循环时(当我想输入第二个学生的信息时),我遇到了麻烦 以下是我到目前为止所做的: #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #i

函数computeScore()用于使用结构数组创建最多50名学生的数据库。该函数接收学生姓名、考试成绩和考试成绩,计算总成绩,然后打印出来。当学生姓名为“end”时,输入将结束。之后,程序将计算所有学生的总平均分数并打印出来

当我输入第一个学生的信息时,它工作正常,但是当程序第二次进入while循环时(当我想输入第二个学生的信息时),我遇到了麻烦

以下是我到目前为止所做的:

#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个字符,然后在结尾追加空字节。这称为最大字段宽度并确保