2015-11-18 4 views
0

Je suis très nouveau au C++, en maintenant ma maîtrise en systèmes d'information. J'ai mon premier devoir C++ annoncé et j'y travaille depuis quelques jours. Le but du code est simplement de lire des informations à partir d'un fichier texte et de les imprimer à l'écran, puis de faire des calculs sur certains d'entre eux et d'imprimer les résultats dans un nouveau fichier texte. Cependant quand je construis, il donne l'erreur:Impossible de résoudre EXC_BAD_ACCESS (code = EXC_I386_GBFLT)

EXC_BAD_ACCESS (code=EXC_I386_GBFLT)

dans le premier fscanf dans la fonction readInfo.

Je sais que le code que j'ai écrit n'est pas complètement efficace mais je veux juste qu'il imprime sur l'écran et sur le fichier de sortie correctement. J'apprécierais vraiment si quelqu'un m'aide à résoudre cette erreur. Je suis sur le point de paniquer ...

#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

+0

Etes-vous sûr que fscanf se bloque? Notes de côté: 'strcpy (studentList [* count] .name, studentList [* count] .name);' est un non-sens. le nom de famille est un caractère, vous lisez seulement un caractère mais vous 'strcat (..., & nom de famille)'. Strcat-ING un char ne fonctionnera pas. –

+0

Oui, je crois que c'est fscanf, puisque l'erreur est affichée sur cette ligne (Screenshot). Je ne sais pas si montrer l'erreur sur cette ligne signifie autre chose. J'essaie de mettre les informations de nom et de nom du fichier txt dans studentList [i] .name. En plus de mon code est un non-sens, j'apprécierais si vous pouvez me guider pour le faire correctement ... –

+1

'* count ++' ne fait pas ce que vous pensez qu'il fait. Il incrémente d'abord le pointeur 'count', puis le déréférence. C'est probablement ce qui provoque le crash. Vous devez écrire '(* count) ++'. – MicroVirus

Répondre

1

L'accident est très probablement causée par une fscanf suivie par strcpy et/ou par incrément de count à l'intérieur readInfo.

Vous écrivez *count++, mais cela équivaut à

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

Qu'est-ce que vous voulez est (*count)++.

Les caractères fscanf scans %c où vous souhaitez analyser des chaînes %s (pour id et name). Vous voulez également analyser surname comme une chaîne, sans doute, mais alors vous devez changer surname être un tableau de caractères:

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); 

J'ai aussi retiré la première strcpy que vous copiez à partir d'un tampon à lui-même, qui est interdit.

Je n'ai pas vérifié les autres fonctions à fond, mais je remarque que vous n'utilisez pas le résultat de votre readInfo appelé de main quand vous faites courseGradeOutput: cette fonction appelle readInfo à nouveau. Vous pouvez le modifier pour prendre les enregistrements d'étudiant lus et le nombre, ainsi vous ne devez pas lire le dossier encore.

Vous pouvez également améliorer scanf un peu pour passer une largeur, comme %29s pour name, afin d'éviter déborder le tampon lorsque le name dans le fichier est trop long; et la même chose pour les autres chaînes que vous scannez. Vous devez ensuite également regarder la valeur de retour de fscanf et utiliser uniquement les éléments que vous avez analysés lorsqu'il a réussi à analyser chaque argument.

+0

Merci beaucoup pour votre aide. Je suis dessus ... –

+0

Content de l'entendre. Vous pouvez accepter la réponse si elle a résolu votre problème, en utilisant la coche grise/verte à côté de la réponse. – MicroVirus