Đọc dữ liệu từ một file khác và tính số điểm trung bình

c

(nya nguyen) #1

mọi người cho mình hỏi là chương trình mình viết như thế này, dịch thì ok nhưng khi run thử thì lại bị lỗi segmentation fault (core dumped) là sao vậy?

code
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef struct seiseki{
  int people;
  int number;
  int *score;
  int size_score;
  double ave;
  char hyouka;
}Score;

void calcAverage(Score *scores);
void hyouka(Score *scores);

int main(){
  FILE *rfp;
  Score *scores;
  int i,j;
  
  rfp = fopen("score.dat","r");
  if(rfp == NULL){
    fprintf(stderr, "error! can't open file!\n");
    exit(1);
  }
  fscanf(rfp, "%d",&scores->people);
  scores = (Score *)malloc(scores->people*sizeof(Score));
  for(i=0; i<scores->people; i++){
    fscanf(rfp, "%d %d", &scores[i].number, &scores[i].size_score);
    printf("-----------------------------\n");
    printf("ID: %d\n",scores[i].number);
    scores[i].score = (int*)malloc(scores[i].size_score*sizeof(int));
    for(j=1; j<=scores[i].size_score; j++){
      fscanf(rfp, "%d", &scores[i].score[j-1]);
      printf("Score %d: %d\n",j, scores[i].score[j-1]);
    }
    calcAverage(&scores[i]);
    hyouka(&scores[i]);
    printf("average: %f\n",scores[i].ave );
    printf("hyouka: %c\n",scores[i].hyouka);
  }
  return 0;
}

void calcAverage(Score *scores){
  int i;
  scores->ave = 0;
  for(i=0; i<=scores->size_score; i++){
    scores->ave += scores->score[i];
  }
  scores->ave /= scores->size_score;
}

void hyouka(Score *scores){
  if(scores->ave >=90)
    printf("S\n");
  else if(scores->ave >=80)
    printf("A\n");
  else if(scores->ave >=70)
    printf("B\n");
  else if(scores->ave >=60)
    printf("C\n");
  else
    printf("D\n");
}

nội dung file score.dat nó như thế này:

  • số lượng học sinh: 50
  • mã số: 10001…
  • số môn học đăng kí: 3…
  • số điểm của từng môn: 20,50,50…
nội dung
50 
10001 3 20 50 50       
10002 5 20 40 40 40 20     
10003 3 20 20 20       
10004 2 40 50        
10005 3 20 40 40       
10006 3 20 40 40       
10007 5 20 40 40 40 20     
10008 9 20 50 50 50 20 50 50 50 20 
10009 2 40 40        
10010 3 20 40 40       
10011 2 50 40        
10012 5 20 40 40 40 20     
10013 3 20 40 40       
10014 2 70 50        
10015 5 20 40 40 40 20     
10016 6 70 40 40 40 70 40    
10017 2 50 70        
10018 9 20 70 70 70 20 70 70 70 20 
10019 5 20 70 70 70 20     
10020 7 40 70 70 70 40 70 70   
10021 8 20 40 40 40 20 40 40 40  
10022 10 50 40 40 40 50 40 40 40 50 40
10023 5 20 50 50 50 20     
10024 9 40 50 50 50 40 50 50 50 40 
10025 3 40 50 50       
10026 4 20 20 20 20      
10027 5 20 20 20 20 20     
10028 7 40 50 50 50 40 50 50   
10029 3 40 40 40       
10030 5 20 40 40 40 20     
10031 3 50 40 40       
10032 7 50 20 20 20 50 20 20   
10033 9 40 20 20 20 40 20 20 20 40 
10034 5 20 40 40 40 20     
10035 7 70 40 40 40 70 40 40   
10036 3 70 50 50       
10037 5 20 40 40 40 20     
10038 6 50 50 50 50 50 50    
10039 7 50 40 40 40 50 40 40   
10040 9 50 40 40 40 50 40 40 40 50 
10041 10 20 40 40 40 20 40 40 40 20 50
10042 5 40 40 40 40 40     
10043 7 20 40 40 40 20 40 40   
10044 3 50 70 70       
10045 5 40 50 50 50 40     
10046 3 20 50 50       
10047 7 20 40 40 40 20 40 40   
10048 9 70 40 40 40 70 40 40 40 70 
10049 5 50 40 40 40 50     
10050 7 20 40 40 40 20 40 40   

mình đã làm được rồi, cảm ơn mọi người nhiều

kết quả
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>

typedef struct seiseki{
  int number; //ID
  int *score;
  int size_score;
  double ave;
  char hyouka;
}Score;

void calcAverage(Score *scores);
void hyouka(Score *scores);

int main(){
  FILE *rfp, *wfp;
  Score *scores;
  int i,j,N;

  rfp = fopen("score.dat","r");
  if(rfp == NULL){
    fprintf(stderr, "error! can't open file!\n");
    exit(1);
  }
  wfp = fopen("kekka.dat","w");
  if(wfp == NULL){
    fprintf(stderr,"error! can't open file!\n");
    exit(1);
  }
  //総人
  fscanf(rfp, "%d",&N);
  scores = (Score *)malloc(N*sizeof(Score));
  for(i=0; i<N; i++){
    //IDとサイズ
    fscanf(rfp, "%d %d", &scores[i].number, &scores[i].size_score);
    fprintf(wfp,"-----------------------------\n");
    fprintf(wfp,"ID: %d\n",scores[i].number);
    scores[i].score = (int*)malloc(scores[i].size_score*sizeof(int));
    //点数表示
    for(j=1; j<=scores[i].size_score; j++){
      fscanf(rfp, "%d", &scores[i].score[j-1]);
      fprintf(wfp,"Score %d: %d\n",j, scores[i].score[j-1]);
    }
    fprintf(wfp,"\n");
    calcAverage(&scores[i]);
    hyouka(&scores[i]);
    fprintf(wfp,"average: %f\n",scores[i].ave );
    fprintf(wfp,"hyouka: %c\n",scores[i].hyouka);
  }
  fclose(rfp);
  fclose(wfp);
  return 0;
}

void calcAverage(Score *scores){
  int i;
  scores->ave = 0;
  for(i=0; i<scores->size_score; i++){
    scores->ave += scores->score[i];
  }
  scores->ave /= scores->size_score;
}

void hyouka(Score *scores){
  if(scores->ave >=90)
    scores->hyouka = 'S';
  else if(scores->ave >=80)
    scores->hyouka = 'A';
  else if(scores->ave >=70)
    scores->hyouka = 'B';
  else if(scores->ave >=60)
    scores->hyouka = 'C';
  else
    scores->hyouka = 'D';
}




(Tao Không Ngu.) #2

Hi nya nguyen

  1. Bạn thưr dùng chương trình debug chưa ?
  2. Các lỗi thường do truy cập vùng nhớ không được phép.

(‏) #3

scores đã trỏ tới đâu đâu mà bạn đi gọi scores->people được?


(nya nguyen) #4

Mình không biết dùng phần mềm debug nào cả, bạn có thể chỉ cho minh được ko?


(nya nguyen) #5

Mình tạo một con trỏ scores theo struct seiseki và scanf dữ liệu từ file score.dat cho vào scores->people mà bạn


(nya nguyen) #6

có ai giúp mình cái vấn đề này với không


(Tao Không Ngu.) #7

Hi nya nguyen.

  1. Score *scores; Chỉ là khai báo một biến con trỏ chứ bạn chưa gán nó trỏ đến vùng nhớ nào. Giống như bạn khai báo 1 biến nhưng chưa gán giá trị cho nó.
  2. fscanf(rfp, “%d”,&scores->people); Vì bạn chưa gán cho nó đến vùng nhớ nào nên lỗi. Giống như khi mua hàng online bạn có chỗ điền địa chỉ nhận hàng nhưng không điền vào thì người giao hàng không chuyển được hàng vậy.
  3. VS có công cụ debug luôn trong đó.

P/S Bạn nên đầu tư thời gian hơn nữa học lập trình còn nếu chỉ học cho có thì phần con trỏ có thể bỏ qua.


(nya nguyen) #8

đau thật, học hết mức có thể rồi mà lại bị ai đó nói là học cho có như thế này thì công nhận đau thật.

Mình cũng tìm được lỗi rồi. đúng là có lỗi ở phần score->people thật.
Nhưng phần scores thì không có lỗi,theo mình thấy thì mình đã tạo ra vùng nhớ cho nó rồi, và giá trị của nó được scan từ file score.dat sang.
Mình học bằng tiếng nhật nên mấy cái thuật ngữ bên việt nam vẫn hay dùng trong IT thì mình mù tịt thôi, không biết VS nó là phần mềm nào luôn.


83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?