无法解析 EXC_BAD_ACCESS(代码=EXC_I386_GBFLT)

Cannot resolve EXC_BAD_ACCESS (code=EXC_I386_GBFLT)

我是 C++ 的新手,正在维护我的 M.Sc 信息系统。我宣布了我的第一个 C++ 家庭作业,并且已经为此工作了几天。该代码的目的只是从文本文件中读取信息并将其打印在屏幕上,然后对其中的一些进行计算并将结果打印到新的文本文件中。但是当我构建时,它给出了错误:

EXC_BAD_ACCESS (code=EXC_I386_GBFLT)

在 readInfo 函数的第一个 fscanf 中。

我知道我写的代码不是完全有效,但我只是希望它能正确地打印在屏幕上和输出文件上。如果有人帮助我解决此错误,我将不胜感激。我快要崩溃了...

#include <stdio.h>

typedef struct {
    char id[10];
    char name[40];
    float midterm;
    float final;
    int attendance;
}Student;


void readInfo(Student studentList[], int *count)
{
    FILE *fin=fopen("scores.txt","r");

    char surname = '[=12=]';
    *count=0;
    while(!feof(fin))
    {
        fscanf(fin,"%c %c %c %f %f %d",studentList[*count].id, studentList[*count].name, &surname, &studentList[*count].midterm, &studentList[*count].final, &studentList[*count].attendance);

        strcpy(studentList[*count].name, studentList[*count].name);
        strcat(studentList[*count].name, " ");
        strcat(studentList[*count].name, &surname);

        *count++;
    }fclose(fin);

    printf("%-7s%17s %5.1f %5.1f %-2d\n", studentList[*count].id, studentList[*count].name, studentList[*count].midterm, studentList[*count].final, studentList[*count].attendance);
}

float studentScore(float midterm, float final, int attendance)
{
    float score;
    int maxAttend=0;
    char id[10];
    char name[40];
    char surname[40];

    FILE *fin=fopen("scores.txt","r");

    while(!feof(fin))
    {
        fscanf(fin,"%c %c %c %f %f %d",id, name, surname, &midterm, &final, &attendance);

        if(attendance>maxAttend)
            maxAttend=attendance;

    }fclose(fin);

    score=midterm*0.3+final*0.5+(maxAttend/20)*attendance;

    return score;

}

float avgScore(Student studentList[])
{
    float average;

    int count;

    int totalScore=0;

    readInfo(studentList, &count);

    for(int i=0; i<=count; i++)
    {
        totalScore+=studentScore(studentList[count].midterm, studentList[count].final, studentList[count].attendance);
    }

    average=totalScore/count;

    return average;
}

void courseGradeOutput(Student studentList[])
{
    FILE *fout=fopen("output.txt","w");

    int count;
    int pass=0;
    float score;
    char letterGrade[2];
    float avg;

    fprintf(fout,"\tId\tName, Surname = (Score, Letter)\n");

    readInfo(studentList, &count);

    for(int i=0; i<=count; i++)
    {
        score=studentScore(studentList[i].midterm, studentList[i].final, studentList[i].attendance);

        if(score>=0 && score<=49)
        {    letterGrade[0]={'F'};
            letterGrade[1]={'F'};}
        else if (score>=50 && score<=59)
        {letterGrade[0]={'F'};
            letterGrade[1]={'D'};}
        else if (score>=60 && score<=64)
        {letterGrade[0]={'D'};
            letterGrade[1]={'D'};}
        else if (score>=65 && score<=69)
        {letterGrade[0]={'D'};
            letterGrade[1]={'C'};}
        else if (score>=70 && score<=74)
        {letterGrade[0]={'C'};
            letterGrade[1]={'C'};}
        else if (score>=75 && score<=79)
        {letterGrade[0]={'C'};
            letterGrade[1]={'B'};}
        else if (score>=80 && score<=84)
        {letterGrade[0]={'B'};
            letterGrade[1]={'B'};}
        else if (score>=85 && score<=89)
        {letterGrade[0]={'B'};
            letterGrade[1]={'A'};}
        else if (score>=90 && score<=100)
        {letterGrade[0]={'A'};
            letterGrade[1]={'A'};}

        if(score>=60)
            pass++;

        fprintf(fout,"%7s %16s = ( %4.1f, %6s\n)", studentList[i].id, studentList[i].name, score, letterGrade);

    }

    avg=avgScore(studentList);

    fprintf(fout,"\nSome statistics:\n\nClass Avg Score: %5.2f \n #Students: %11d \n #Passed Students: %4d \n #Failed Students: %4d",avg,count,pass,(count-pass));

    fclose(fout);

}

int main()
{   Student studentList[100];
    int count;

    readInfo(studentList, &count);

    courseGradeOutput(studentList);
}

Screenshot

崩溃很可能是由 fscanf 后跟 strcpy and/or 引起的 readInfo.[=35= 中 count 的增量]

你写*count++,但这相当于

count = count + 1;
*(count-1);

你要的是(*count)++.

fscanf 扫描字符 %c,其中您想扫描字符串 %s(对于 idname)。您可能还想将 surname 扫描为字符串,但随后您需要将 surname 更改为字符数组:

char surname[30];
*count=0;
while(!feof(fin))
{
    fscanf(fin,"%s %s %s %f %f %d",studentList[*count].id, studentList[*count].name, surname, &studentList[*count].midterm, &studentList[*count].final, &studentList[*count].attendance);

    strcat(studentList[*count].name, " ");
    strcat(studentList[*count].name, surname);

    (*count)++;
}
fclose(fin);

我还删除了第一个 strcpy,因为您正在从缓冲区复制到自身,这是不允许的。

我没有彻底检查其他函数,但我确实注意到当您执行 courseGradeOutput 时,您没有使用从 main 调用的 readInfo 的结果:这个函数再次调用 readInfo。您可以修改它以获取读取的学生记录和计数,这样您就不必再次读取文件。

你可能还想改进一下scanf来传递一个宽度,比如%29sname,以避免当name里面的时候缓冲区溢出文件太长;对于您扫描的其他字符串也是如此。然后,您还应该查看 fscanf 的 return 值,并且仅在成功扫描每个参数时使用您扫描的内容。