30/09/2018, 23:53

Lỗi trong chương trình nhập / xuất thông tin học sinh trong lớp học

Hi mọi người,

Mình có 1 đề bài như sau nhé: Nhập / xuất thông tin của 1 lớp học gồm N học sinh được nhập từ bàn phím, mỗi học sinh gồm: Mã số, họ và tên, điểm các môn (toán , lý , hóa với hệ số tương ứng).

Source code:

Đầu tiên tạo 1 struct về danh sách 3 môn Toán, Lý, Hóa với các hệ số tương ứng kèm điểm trung bình:

  • **subjects.h**
  • ``` #pragma once #include #include #include

    typedef struct subj SUBJ;
    struct subj
    {
    double toan, ly, hoa, diemtb;
    int hstoan, hsly, hshoa;
    char* xeploai;
    };

    void InSubj(SUBJ *); // nhập thông tin các điểm toán, lý, hóa …
    void OutSubj(SUBJ *); // xuất thông tin

    Sau đó tiến hành nhập:
    <li>subjects.cpp</li>
    

    #define _CRT_SECURE_NO_WARNINGS
    #include “subjects.h”

    void InSubj(SUBJ *s)
    {
    printf(" Nhap diem toan: “);
    scanf(”%lf", &s->toan);
    printf(" Nhap he so toan: “);
    scanf(”%d", &s->hstoan);
    printf(" Nhap diem ly: “);
    scanf(”%lf", &s->ly);
    printf(" Nhap he so ly: “);
    scanf(”%d", &s->hsly);
    printf(" Nhap diem hoa: “);
    scanf(”%lf", &s->hoa);
    printf(" Nhap he so hoa: “);
    scanf(”%d", &s->hshoa);
    s->diemtb = ((s->toan * s->hstoan) + (s->ly * s->hsly) + (s->hoa * s->hshoa)) / (s->hstoan + s->hsly + s->hshoa);
    if (s->diemtb < 3)
    s->xeploai = “Kem”;
    else if (s->diemtb < 5)
    s->xeploai = “Yeu”;
    else if (s->diemtb < 6.5)
    s->xeploai = “Trung binh”;
    else if (s->diemtb < 8)
    s->xeploai = “Kha”;
    else if (s->diemtb < 9)
    s->xeploai = “Gioi”;
    else
    s->xeploai = “Xuat sac”;
    }
    void OutSubj(SUBJ *s)
    {
    printf(" Diem toan = %.2lf & he so = %d ", s->toan, s->hstoan);
    printf(" Diem ly = %.2lf & he so = %d ", s->ly, s->hsly);
    printf(" Diem hoa = %.2lf & he so = %d ", s->hoa, s->hshoa);
    printf(" => Diem trung binh = %.1lf ", s->diemtb);
    printf(" => Hoc luc: %s ", s->xeploai);
    }

    **Tiếp theo là tạo 1 struct về thông tin học sinh bao gồm: Mã số, họ và tên, điểm các môn**
    <li>**student.h**</li>
    

    #pragma once
    #include “subjects.h”

    typedef struct stdt STDT;
    struct stdt
    {
    char maso[30];
    char hoten[50];
    SUBJ sub;
    };

    void InStdt(STDT *); // nhập thông tin sinh viên
    void OutStdt(STDT *); // xuất thông tin

    <li>student.cpp</li>
    

    #define _CRT_SECURE_NO_WARNINGS
    #include “student.h”

    void InStdt(STDT *s)
    {
    printf(" Nhap ma so hoc sinh: “);
    scanf(”%s", s->maso);
    printf(" Nhap ho va ten: “);
    while (getchar() != ‘ ’ && getchar() != EOF) {}
    gets_s(s->hoten);
    printf(” Nhap diem: ");
    InSubj(&s->sub);
    }
    void OutStdt(STDT *s)
    {
    printf(" Ma so hoc sinh: %s ", s->maso);
    printf(" Ho va ten: %s ", s->hoten);
    printf(" Thong tin diem: ");
    OutSubj(&s->sub);
    }

    **Cuối cùng, tạo 1 struct về các học sinh trong lớp học:**
    <li>**Class.h**</li>
    

    #pragma once
    #include “student.h”

    typedef struct grade GRADE;
    struct grade
    {
    int nhs;
    STDT *arr;
    };

    void InGrd(GRADE *); // nhập thông tin lớp học
    void OutGrd(GRADE *); // xuất thông tin

    <li>Class.cpp</li>
    

    #define _CRT_SECURE_NO_WARNINGS
    #include “Class.h”

    void InGrd(GRADE *g)
    {
    printf(" Nhap vao so luong hoc sinh: “);
    scanf(”%d", &g->nhs);
    g->arr = (STDT *)malloc(g->nhs * sizeof(STDT));
    for (int i = 0; i < g->nhs; ++i)
    {
    printf(" ---------- Nhap thong tin hoc sinh %d ---------- ", i + 1);
    InStdt(&g->arr[i]);
    }
    }
    void OutGrd(GRADE *g)
    {
    for (int i = 0; i < g->nhs; ++i)
    {
    printf(" ---------- Thong tin hoc sinh %d ---------- ", i + 1);
    OutStdt(&g->arr[i]);
    }
    }

    **Còn đây là hàm main rất đơn giản:**
    

    #include “Class.h”

    int main()
    {
    GRADE *g = (GRADE *)malloc(sizeof(GRADE));
    InGrd(g);
    OutGrd(g);
    free(g->arr);
    free(g);
    getch();
    return 0;
    }

    
    
    ----------
    Bây giờ, đề nó yêu cầu thêm 1 tí là mã số các học sinh khi nhập không được trùng nhau !
    Để làm được điều này, em có chỉnh sửa 1 tí ở file **Class.cpp**, là mỗi khi nhập mã số sẽ kiểm tra lùi về trước đó xem coi có trùng chưa, bằng cách gọi: **g->arr[i]->maso**.
    
    Nhưng khi gọi tới **g->arr[i]->...** thì nó không hiện ra biến `maso` cho chọn.
    
    Còn gõ **g->arr->...** thì nó mới hiện biến `maso` cho chọn. Nhưng nếu thế thì sao truy cập được những thông tin sinh viên ở trước ?
    
    Vậy câu hỏi của em đặt ra là vì sao khi gõ **g->arr[i]->...** thì Visual nó không hiện ra biến `maso` cho mình chọn và làm cách nào để giải quyết vấn đề này ?
    
    Xin cảm ơn mọi người rất nhiều :)
    viết 01:58 ngày 01/10/2018

    g->arr = (STDT *)malloc(g->nhs * sizeof(STDT));

    Bạn nhìn câu lệnh này có thể suy ra được mà, g->arr là một con trỏ (kiểu STDT*) nên khi truy cập thành viên phải dùng toán tử ->. Còn g->arr[i] có kiểu dữ liệu STDT, nên muốn truy cập thành viên của nó phải dùng toán tử .

    Người bí ẩn viết 02:00 ngày 01/10/2018

    Tuyệt vời ông mặt trời

    Bài liên quan
    0