Lỗi khi thêm / xóa học sinh trong danh sách lớp học

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

Nhắc lại đề bài: 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).

Yêu cầu thêm: Hãy thực hiện thao tác thêm / xóa học sinh trong danh sách lớp học đó.

Update source code:

subjects.h

#pragma once
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>

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

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

subjects.cpp

#include "subjects.h"

void InSubj(SUBJ *s)
{
	printf("\nNhap diem toan: ");
	scanf("%lf", &s->toan);
	printf("\nNhap he so toan: ");
	scanf("%d", &s->hstoan);
	printf("\nNhap diem ly: ");
	scanf("%lf", &s->ly);
	printf("\nNhap he so ly: ");
	scanf("%d", &s->hsly);
	printf("\nNhap diem hoa: ");
	scanf("%lf", &s->hoa);
	printf("\nNhap 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)
		strcpy(s->xeploai, "Kem");
	else if (s->diemtb < 5)
		strcpy(s->xeploai, "Yeu");
	else if (s->diemtb < 6.5)
		strcpy(s->xeploai, "Trung Binh");
	else if (s->diemtb < 8)
		strcpy(s->xeploai, "Kha");
	else if (s->diemtb < 9)
		strcpy(s->xeploai, "Gioi");
	else
		strcpy(s->xeploai, "Xuat sac");
}
void OutSubj(SUBJ *s)
{
	printf("\nDiem toan = %.2lf & he so = %d\n", s->toan, s->hstoan);
	printf("\nDiem ly = %.2lf & he so = %d\n", s->ly, s->hsly);
	printf("\nDiem hoa = %.2lf & he so = %d\n", s->hoa, s->hshoa);
	printf("\n=> Diem trung binh = %.1lf\n", s->diemtb);
	printf("\n=> Hoc luc: %s\n", s->xeploai);
}

student.h

#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

student.cpp

#include "student.h"

void InStdt(STDT *s)
{
	printf("\nNhap ho va ten: ");
	while (getchar() != '\n' && getchar() != EOF) {}
	gets_s(s->hoten);
	printf("\nNhap diem:\n");
	InSubj(&s->sub);
}
void OutStdt(STDT *s)
{
	printf("\nMa so hoc sinh: %s\n", s->maso);
	printf("\nHo va ten: %s\n", s->hoten);
	printf("\nThong tin diem:\n");
	OutSubj(&s->sub);
}

class.h

#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

class.cpp

#include "Class.h"

void InGrd(GRADE *g)
{
	printf("\nNhap 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("\n---------- Nhap thong tin hoc sinh %d ----------\n", i + 1);
		bool Check;
		do
		{
			Check = true;
			printf("\nNhap ma so hoc sinh: ");
			scanf("%s", g->arr[i].maso);
			for (int j = i - 1; j >= 0; --j)
			{
				if (stricmp(g->arr[j].maso, g->arr[i].maso) == 0)
				{
					printf("\nMa so hoc sinh bi trung. Moi nhap lai\n");
					Check = false;
					break;
				}
			}
		} while (Check == false);
		InStdt(&g->arr[i]);
	}
}
void OutGrd(GRADE *g)
{
	for (int i = 0; i < g->nhs; ++i)
	{
		printf("\n---------- Thong tin hoc sinh %d ----------\n", i + 1);
		OutStdt(&g->arr[i]);
	}
}

source.cpp (main)

#include <algorithm>
#include "Class.h"

bool LonHon(double a, double b)
{
	return a > b;
}
bool NhoHon(double a, double b)
{
	return a < b;
}
void SortList(GRADE *g, bool(*ptr)(double, double))
{
	for (int i = 0; i < g->nhs - 1; ++i)
	{
		for (int j = i + 1; j < g->nhs; ++j)
		{
			if (ptr(g->arr[i].sub.diemtb, g->arr[j].sub.diemtb))
				std::swap(g->arr[i], g->arr[j]);
		}
	}
}
void Dem_LietkeHocbong(GRADE *g)
{
	int count = 0;
	printf("\nNhung ban nhan duoc hoc bong: ");
	for (int i = 0; i < g->nhs; ++i)
	{
		if (g->arr[i].sub.diemtb >= 8)
		{
			printf("%s. ", g->arr[i].hoten);
			++count;
		}
	}
	printf("\n=> Co tong cong %d ban nhan duoc hoc bong.\n", count);
}
void Dem_LietkeHoclai(GRADE *g)
{
	int count = 0;
	printf("\nNhung ban phai hoc lai: ");
	for (int i = 0; i < g->nhs; ++i)
	{
		if (g->arr[i].sub.toan < 5 || g->arr[i].sub.hoa < 5 || g->arr[i].sub.ly < 5)
		{
			printf("%s. ", g->arr[i].hoten);
			++count;
		}
	}
	printf("\n=> Co tong cong %d ban phai hoc lai.\n", count);
}
void TimKiemThongTin(GRADE *g, char* maso)
{
	bool Check = false;
	for (int i = 0; i < g->nhs; ++i)
	{
		if (stricmp(g->arr[i].maso, maso) == 0)
		{
			OutStdt(&g->arr[i]);
			Check = true;
			break;
		}
	}
	if (Check == false)
		printf("\nMa so hoc sinh khong ton tai!\n");
}
void AddStd(GRADE *&g, STDT *sv, int vitrithem)
{
	g->arr = (STDT *)realloc(g->arr, (g->nhs + 1) * sizeof(STDT));
	g->arr[g->nhs] = *sv;
	for (int i = g->nhs; i > vitrithem; --i)
	{
		std::swap(g->arr[i], g->arr[i - 1]);
	}
	++(g->nhs);
}
int main()
{
	/* ------------ NHẬP / XUẤT DANH SÁCH LỚP HỌC ------------ */

	GRADE *g = (GRADE *)malloc(sizeof(GRADE));
	InGrd(g);
	OutGrd(g);

	/* ------------ SẮP XẾP TĂNG/GIẢM DẦN DANH SÁCH LỚP HỌC ------------ */

	printf("\nDanh sach lop hoc sau khi sap xep tang dan\n");
	SortList(g, LonHon); // GiamDan
	OutGrd(g);

	/* ------------ ĐẾM VÀ LIỆT KÊ NHỮNG BẠN ĐƯỢC HỌC BỔNG / HỌC LẠI ------------ */

	Dem_LietkeHocbong(g);
	Dem_LietkeHoclai(g);
	char* maso = (char *)calloc(30, sizeof(char));
	printf("\nNhap ma so hoc sinh can tim: ");
	scanf("%s", maso);

	/* ------------ TÌM KIẾM THÔNG TIN HỌC SINH ------------ */

	TimKiemThongTin(g, maso);

	/* ------------ THÊM/XÓA HỌC SINH ------------ */

	STDT *sv = (STDT *)malloc(sizeof(STDT));
	int vitrithem;
	do
	{
		printf("\nNhap vi tri can them hoc sinh trong danh sach: ");
		scanf("%d", &vitrithem);
		if (vitrithem < 0 || vitrithem > g->nhs)
			printf("\nVi tri them khong hop le\n");
	} while (vitrithem < 0 || vitrithem > g->nhs);
	printf("\nNhap thong tin hoc sinh can them:\n");
	printf("\nNhap ma so: ");
	scanf("%s", sv->maso);
	InStdt(sv);
	printf("\nResult:\n");
	OutGrd(g);

	/* ------------ GIẢI PHÓNG CÁC CON TRỎ ------------ */

	free(sv);
	free(g->arr);
	free(g);
	getch();
	return 0;
}

Mình làm hàm thêm trước. Như ở trong file source.cpp.

Vấn đề: Khi thêm học sinh thì mọi việc đều diễn ra bình thường. Nhưng khi xuất ra lại danh sách thì cái thông tin sinh viên vừa thêm lại không có hiển thị ra. Vì sao lại thế ?

Giúp mình nhé mọi người, xin cảm ơn :slight_smile:

Chạy debug xem chết ở dòng nào.

1 Like

Em debug roi` nhung khong tim dc loi anh :cry:

Còn vì sao nó ko được in ra vì bạn chưa thêm sv mới vào lớp.

Thêm đoạn nhỏ này trước khi in or sau khi nhập xong là được

g->arr = (STDT *)realloc(g->arr, (g->nhs + 1) * sizeof(STDT));
g->arr[g->nhs] = *sv;
g->nhs++;
3 Likes

Mình đã tìm ra lỗi, có phần gợi ý của anh @drgnz

Lỗi rất ngớ ngẩn là chưa (quên) gọi hàm AddStd (thêm sinh viên) ở trong hàm Main nên nó không thêm :cry:

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