无法解析EXC_BAD_ACCESS(代码=EXC_I386_GBFLT)

Cannot resolve EXC_BAD_ACCESS (code=EXC_I386_GBFLT)

本文关键字:EXC 代码 I386 GBFLT BAD ACCESS      更新时间:2023-10-16

我是C++的新手,负责维护我的信息系统硕士学位。我已经宣布了我的第一个C++作业,并且已经做了几天了。代码的目的只是从文本文件中读取信息并将其打印在屏幕上,然后对其中的一些信息进行计算并将结果打印到新的文本文件中。然而,当我构建时,它给出了错误:

EXC_BAD_ACCESS(代码=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 = '';
    *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 %-2dn", 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,"tIdtName, 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, %6sn)", studentList[i].id, studentList[i].name, score, letterGrade);
    }
    avg=avgScore(studentList);
    fprintf(fout,"nSome statistics:nnClass 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);
}

屏幕截图

崩溃很可能是由fscanf后面跟着strcpy和/或readInfocount的增量引起的。

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

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

你想要的是(*count)++

fscanf扫描要扫描字符串%s(用于idname)的字符%c。您可能还想将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以传递宽度,例如name%29s,以避免在文件内的name过长时溢出缓冲区;您扫描的其他字符串也是如此。然后,您还应该查看fscanf的返回值,并且只使用在成功扫描每个参数时扫描的内容。