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