无法解析EXC_BAD_ACCESS(代码= EXC_I386_GBFLT)

时间:2015-11-18 13:40:39

标签: c++ fopen exc-bad-access scanf stdio

我是C ++的新手,在信息系统上维护我的硕士学位。我已经宣布了我的第一个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 = '\0';
    *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

1 个答案:

答案 0 :(得分:1)

崩溃很可能是由fscanf后跟strcpy和/或count readInfo内的*count++增加造成的。

你写count = count + 1; *(count-1); ,但这相当于

(*count)++

你想要的是fscanf

%c会扫描您要扫描字符串%s的字符idnamesurname)。您可能也希望将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

当你从缓冲区复制到自身时,我也删除了第一个readInfo,这是不允许的。

我没有彻底检查其他功能,但是我注意到当你执行main时,你不会使用来自courseGradeOutput的{​​{1}}的结果:此函数调用再次readInfo。您可以对其进行修改以获取读取的学生记录和计数,因此您不必再次阅读该文件。

您可能还希望稍微改进scanf以传递宽度,例如%29s name,以避免在文件内name时溢出缓冲区太长;和你扫描的其他字符串相同。然后,您还应该查看fscanf的返回值,并仅在成功扫描每个参数时使用您扫描的内容。