无法解析 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);
}
崩溃很可能是由 fscanf
后跟 strcpy
and/or 引起的 readInfo
.[=35= 中 count
的增量]
你写*count++
,但这相当于
count = count + 1;
*(count-1);
你要的是(*count)++
.
fscanf
扫描字符 %c
,其中您想扫描字符串 %s
(对于 id
和 name
)。您可能还想将 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
来传递一个宽度,比如%29s
为name
,以避免当name
里面的时候缓冲区溢出文件太长;对于您扫描的其他字符串也是如此。然后,您还应该查看 fscanf
的 return 值,并且仅在成功扫描每个参数时使用您扫描的内容。
我是 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);
}
崩溃很可能是由 fscanf
后跟 strcpy
and/or 引起的 readInfo
.[=35= 中 count
的增量]
你写*count++
,但这相当于
count = count + 1;
*(count-1);
你要的是(*count)++
.
fscanf
扫描字符 %c
,其中您想扫描字符串 %s
(对于 id
和 name
)。您可能还想将 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
来传递一个宽度,比如%29s
为name
,以避免当name
里面的时候缓冲区溢出文件太长;对于您扫描的其他字符串也是如此。然后,您还应该查看 fscanf
的 return 值,并且仅在成功扫描每个参数时使用您扫描的内容。