


















Preview text:
lOMoAR cPSD| 61570513
TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN TOÁN ỨNG DỤNG & TIN HỌC
Báo cáo môn Kỹ thuật lập trình
Chủ đề: Quản lý sinh viên
Giáo viên hướng dẫn: Nguyễn Thị Thanh Huyền
Họ và tên sinh viên: Đàm Thị Anh MSSV: 20216793 Lớp: Toán Tin 01 K66 Mã lớp học: 142298 lOMoAR cPSD| 61570513 Mục lục
1. Trình bày bài toán ......................................................................................................... 4
2. Thiết kế chương trình theo phương pháp tinh chỉnh từng bước.............................. 6 lOMoAR cPSD| 61570513
3. Mã nguồn: .................................................................................................................... 20
4. Kết quả ra của chương trình ...................................................................................... 46
Kết quả file output: ...................................................................................................... 46
Kết quả màn hình: ........................................................................................................ 53
5. Kết luận, đánh giá những kết quả đạt được, những ưu điểm và những thiếu sót 61 lOMoAR cPSD| 61570513 1. Trình bày bài toán
Bài toán: Quản lý thông tin sinh viên và điểm học phần Mô tả bài toán:
Trường Đại học XYZ muốn quản lý thông tin của sinh viên và điểm học phần trong các file nhị phân.
Hệ thống cần hỗ trợ các thao tác bổ sung, xóa, và sửa chữa dữ liệu trong 3 file SV.BIN, HP.BIN, và
DIEMTHI.BIN và đồng thời đảm bảo các yêu cầu sau:
1. File SV.BIN chứa thông tin về sinh viên với các trường dữ liệu: - Mã số sinh viên (mssv)
- Họ đệm và Tên sinh viên - Giới tính - Ngày sinh
2. File HP.BIN chứa thông tin về các học phần với các trường dữ liệu: - Mã học phần (mahp)
- Tên môn học - Số tín chỉ
3. File DIEMTHI.BIN chứa thông tin điểm thi với các trường dữ liệu: - Mã học phần (mahp) - Mã số sinh viên (mssv) - Điểm học phần (diem)
Yêu cầu về dữ liệu:
- Không có 2 bản ghi nào trong SV.BIN giống nhau trên Mã số sinh viên.
- Không có 2 bản ghi nào trong HP.BIN giống nhau trên Mã học phần.
- Không có 2 bản ghi nào trong DIEMTHI.BIN đồng thời giống nhau trên Mã học phần và Mã số sinh viên.
Các chức năng cần hỗ trợ:
- Bổ sung thông tin sinh viên vào file SV.BIN
- Bổ sung thông tin học phần vào file HP.BIN
- Bổ sung thông tin điểm thi vào file DIEMTHI.BIN
- Xóa thông tin sinh viên khỏi file SV.BIN
- Xóa thông tin học phần khỏi file HP.BIN
- Xóa thông tin điểm thi khỏi file DIEMTHI.BIN lOMoAR cPSD| 61570513
- Sửa thông tin sinh viên trong file SV.BIN
- Sửa thông tin học phần trong file HP.BIN
- Sửa thông tin điểm thi trong file DIEMTHI.BIN
Các ràng buộc dữ liệu cần thực hiện:
- Khi bổ sung thông tin điểm thi vào DIEMTHI.BIN, mọi mã học phần trong file DIEMTHI phải là
một mã học phần trong file HP.BIN
- Khi bổ sung thông tin điểm thi vào DIEMTHI.BIN, mọi Mã sinh viên trong file DIEMTHI phải là
một Mã sinh viên trong file SV.BIN .
- Ngày sinh được nhập vào theo đúng định dạng ngày tháng.
- Điểm học phần là một số thực gồm 1 chữ số sau dấu phẩy, thuộc khoảng [0..10] và lẻ đến 0.5 (thang điểm 10).
Các tính năng bổ sung:
- Tính điểm trung bình chung tích lũy theo thang điểm 4 của từng sinh viên và ghi vào file nhị phân DTL.BIN .
- Hiển thị Tên học phần và danh sách gồm mã số, họ tên sinh viên và điểm học phần của các sinh viên khi nhập mã học phần.
- Hiển thị danh sách gồm mã số, họ tên của những sinh viên không đạt học phần khi nhập mã học phần.
- Hiển thị danh sách các học phần mà sinh viên chưa đạt khi nhập mã sinh viên.
- Hiển thị điểm trung bình chung tích lũy của sinh viên khi nhập mã sinh viên.
Yêu cầu phần mềm:
- Phần mềm cần được cài đặt bằng menu điều khiển bằng các phím chức năng để thực hiện các chức năng cần hỗ trợ.
- Ghi vào tệp văn bản để thể hiện quá trình thực hiện chương trình và các kết quả ra lOMoAR cPSD| 61570513
2. Thiết kế chương trình theo phương pháp tinh chỉnh từng bước Bước 0: lOMoAR cPSD| 61570513
Bước 1: Khai báo cấu trúc hàm SinhVien, HocPhan, DiemThi - struct SinhVien:
mssv: Mã số sinh viên, kiểu char array (c-string) có độ dài tối đa là 10 ký tự.
hodem: Họ đệm của sinh viên, kiểu char array (c-string) có độ dài tối đa là 50 ký tự.
ten_sv: Tên của sinh viên, kiểu char array (c-string) có độ dài tối đa là 50 ký tự. gioi_tinh:
Giới tính của sinh viên, kiểu char array (c-string) có độ dài tối đa là 10 ký tự.
ngay_sinh: Ngày sinh của sinh viên, kiểu char array (c-string) có độ dài tối đa là 11 ký tự (dd/mm/yyyy). - struct HocPhan:
mahp: Mã học phần, kiểu char array (c-string) có độ dài tối đa là 10 ký tự. ten_mon_hoc:
Tên môn học, kiểu char array (c-string) có độ dài tối đa là 50 ký tự.
so_tc: Số tín chỉ của học phần, kiểu int. - struct DiemThi:
mahp: Mã học phần, kiểu char array (c-string) có độ dài tối đa là 10 ký tự. mssv:
Mã số sinh viên, kiểu char array (c-string) có độ dài tối đa là 10 ký tự.
diem: Điểm thi của sinh viên, kiểu float.
Bước 2: Kiểm tra định dạng ngày sinh, điểm học phần -
Hàm kiểm tra định dạng ngày sinh: bool KiemTraNgaySinh(const char* ngay_sinh)
+ Đầu vào: con trỏ constr char* ngay_sinh
+ Đầu ra: true nếu đúng định dạng và false nếu ngược lại
Kiểm tra độ dài ngày sinh:
if (strlen(ngay_sinh) != 10), yêu cầu nhập lại, return false
Kiểm tra tính hợp lệ của ngày tháng năm: nếu sai yêu cầu nhập lại, return false else return true -
Kiểm tra xem điểm thi nằm từ 0 đến 10 và lẻ đến 0.5 hay không: bool kiemTraDiem(float diem)
+ Đầu vào: diem là số thực (float)
+ Đầu ra: true nếu đúng và false nếu ngược lại bool kiemTraDiem(float diem) {
if(diem >= 0.0 && diem <= 10.0 && static_cast(diem * 10) % 5 == 0) { return true; lOMoAR cPSD| 61570513 } return false;
Bước 3: Nhập thông tin sinh viên, học phần, điểm thi
Nhập thông tin sinh viên SinhVien NhapSV() Đầu vào:
Đầu ra: biến sv lưu thông tin sinh viên
• Khai báo và định nghĩa hàm “NhapSV()” để nhập thông tin của một sinh viên
• Tạo biến “SinhVien sv” để lưu thông tin sinh viên
• Yêu cầu người dùng nhập các yêu cầu: mssv, hodem, ten_sv, gioi_tinh
• Sử dụng một vòng lặp “do-while” để yêu cầu nhập ngày sinh (sv.ngay_sinh) trong đúng định
dạng dd/mm/yyyy và kiểm tra tính hợp lệ của ngày sinh bằng hàm KiemTraNgaySinh() bool
hopLe = false ; do { cout << "Nhap ngay sinh (theo dang
dd/mm/yyyy): "; cin.getline(sv.ngay_sinh, 11); hopLe =
KiemTraNgaySinh(sv.ngay_sinh); } while (!hopLe) ;
• Sau khi nhập sinh viên hợp lệ, trả về thông tin Sinh viên (SinhVien sv) vừa nhập.
Nhập thông tin học phần HocPhan nhap_hp() Đầu vào:
Đầu ra: biến hp lưu thông tin học phần
• Khai báo và định nghĩa hàm “nhap_hp()” để nhập thông tin của một học phần.
• Tạo một biến “HocPhan hp” để lưu thông tin học phần.
• Nhập: mahp, ten_mon_hoc, so_tc
• Trả về thông tin học phần (HocPhan hp) vừa nhập
Nhập thông tin điểm thi DiemThi nhap_diem_thi() Đầu vào:
Đầu ra: biến dt lưu thông tin điểm thi
• Khai báo và định nghĩa hàm “nhap_diem_thi” để nhập thông tin về điểm thi
• Tạo 1 biến “DiemThi dt” để lưu thông tin điểm thi lOMoAR cPSD| 61570513 • Nhập: mahp, mssv, diem
• Sử dụng một vòng lặp do-while để yêu cầu nhập điểm (dt.diem) trong khoảng từ 0.0 đến 10.0. do {
cout << "Nhap diem (0.0 - 10.0): "; cin >> dt.diem ;
hopLe = kiemTraDiem(dt.diem) ; }while (!hopLe) ;
• Sau khi nhập điểm hợp lệ, trả về thông tin điểm thi (DiemThi dt) vừa nhập.
Bước 4: ghi và đọc file SV.BIN, HOCPHAN.BIN, DIEMTHI.BIN
Hàm ghi file (SV.BIN, HP.BIN, DIEMTHI.BIN)
Đầu vào: const SinhVien& sv, const HocPhan & hp, const DiemThi& dt Đầu ra:
• Mở file để ghi dữ liệu bằng cách sử dụng ofstream với chế độ ios::binary | ios::app.
• Sử dụng hàm write để ghi dữ liệu của đối tượng sinh viên sv vào file dưới dạng nhị phân, với
kích thước là sizeof(….).
if (binFile.is_open()) { binFile.write(reinterpret_castchar*>(&...),sizeof(...)); binFile.close(); cout <<
"Ghi sinh vien vao file ... BIN thanh cong" << endl;
} else { cout << "Khong the mo file SV.BIN" << endl; }
• Đóng file sau khi ghi xong thông tin.
Hàm đọc file: (SV.BIN, HP.BIN, DIEMTHI.BIN)
• Mở file để đọc dữ liệu bằng cách sử dụng ifstream với chế độ ios::binary.
• Sử dụng vòng lặp while kết hợp với hàm read để đọc dữ liệu từ file vào biến sv với kích thước là sizeof(SinhVien).
while (binFile.read(reinterpret_cast(&...), sizeof(...)))
• Hiển thị thông tin vừa đọc được của sinh viên lên màn hình.
• Lặp lại quá trình cho đến khi đọc hết dữ liệu trong file.
• Đóng file sau khi đọc xong thông tin.
Bước 5: Hàm kiểm tra trùng lặp mssv, mahp
Kiểm tra trùng lặp trong file SV.BIN bool checkDuplicateMSSV
Đầu vào: con trỏ trỏ mssv lOMoAR cPSD| 61570513
Đầu ra: false không trùng mssv, true nếu ngược lại
• Mở tập tin SV.BIN để đọc thông tin về sinh viên.
• Đọc dữ liệu từ tập tin SV.BIN bằng vòng lặp while:
+ Đọc một bản ghi từ tập tin SV.BIN vào biến sv kiểu SinhVien.
+ So sánh mã số sinh viên (sv.mssv) với mã số sinh viên (mssv) được truyền vào. Nếu trùng
khớp, đóng tập tin và trả về true.
• Đóng tập tin SV.BIN.
• Nếu không tìm thấy mã số sinh viên trùng khớp, trả về false.
+ Hàm kiểm tra trùng lặp Mã học phần trong file HP.BIN bool checkDuplicateMaHP
Đầu vào: con trỏ trỏ mahp
Đầu ra: false nếu không trùng mahp, true nếu ngược lại
• Mở tập tin HP.BIN để đọc thông tin về học phần.
• Đọc dữ liệu từ tập tin HP.BIN bằng vòng lặp while:
+ Đọc một bản ghi từ tập tin HP.BIN vào biến hp kiểu HocPhan.
+ So sánh mã học phần (hp.mahp) với mã học phần (mahp) được truyền vào. Nếu trùng khớp,
đóng tập tin và trả về true.
• Đóng tập tin HP.BIN.
• Nếu không tìm thấy mã học phần trùng khớp, trả về false.
Hàm kiểm tra trùng lặp Mã học phần và Mã số sinh viên trong file DIEMTHI.BIN bool checkDuplicateDiem
Đầu vào: con trỏ trỏ mahp, mssv
Đầu ra: false nếu không trùng, true nếu ngược lại
• Mở tập tin DIEMTHI.BIN để đọc thông tin về điểm thi của sinh viên.
• Đọc dữ liệu từ tập tin DIEMTHI.BIN bằng vòng lặp while:
+ Đọc một bản ghi từ tập tin DIEMTHI.BIN vào biến dt kiểu DiemThi.
+ So sánh mã học phần (dt.mahp) với mã học phần (mahp) và mã số sinh viên (dt.mssv) với
mã số sinh viên (mssv) được truyền vào. Nếu cả hai điều kiện đều trùng khớp, đóng tập tin và trả về true.
• Đóng tập tin DIEMTHI.BIN. lOMoAR cPSD| 61570513
• Nếu không tìm thấy thông tin điểm trùng khớp, trả về false.
Bước 5: Bổ sung dữ liệu Bổ sung file SV.BIN void bosungSV() Đầu vào:
Đầu ra: Thông tin sinh viên
• Kiểm tra xem mssv đã tồn tại trong file SV.BIN hay chưa bằng cách gọi hàm checkDuplicateMSSV(sv.mssv).
• Nếu mssv đã tồn tại, kết thúc hàm
• Nếu mã số sinh viên không tồn tại, ghi thông tin của sinh viên vào file SV.BIN bằng cách gọi hàm ghiSinhVien(sv)
Bổ sung file HOCPHAN.BIN void bosungHP Đầu vào:
Đầu ra: Thông tin sinh viên
• Kiểm tra xem mahp đã tồn tại trong file HP.BIN hay chưa bằng cách gọi hàm checkDuplicateMAHP(hp.mahp)
• Nếu mssv đã tồn tại, kết thúc hàm
• Nếu mã số sinh viên không tồn tại, ghi thông tin của sinh viên vào file SV.BIN bằng cách gọi hàm ghiHocPhan(hp)
Bổ sung file DIEMTHI.BIN void bosungDiem Đầu vào: Đầu ra: Thông tin điểm
• Kiểm tra xem mssv và mahp đã tồn tại trong file DIEM.BIN hay chưa bằng cách gọi hàm
checkDuplicateMSSV(sv.mssv) và checkDuplicateMAHP(hp.mahp)
• Nếu mssv và mahp đã tồn tại, kết thúc hàm
• Nếu mã số sinh viên không tồn tại, ghi thông tin của sinh viên vào file SV.BIN bằng cách gọi hàm ghiDiemThi (dt)
Bước 6: Xóa dữ liệu
Xóa dữ liệu trong file SV.BIN void xoaSinhVien Đầu vào: mssv lOMoAR cPSD| 61570513
Đầu ra: dữ liệu đã được xóa
• Mở file nhị phân SV.BIN: ifstream inFile("SV.BIN", ios::binary);
• Mở file temp.BIN để tạo một file tạm để sao chép thông tin sinh viên không bị xóa:
ofstream tempFile("temp.BIN", ios::binary);
• Lặp qua từng bản ghi trong file SV.BIN bằng cách sử dụng vòng lặp while.
▪ Trong mỗi lần lặp, đọc một bản ghi từ file SV.BIN và kiểm tra mã số sinh viên của bản ghi đó.
▪ Nếu mã số sinh viên không trùng khớp với mã số sinh viên cần xóa, sao chép bản ghi đó vào
file tạm temp.BIN bằng cách sử dụng tempFile.write().
while (inFile.read(reinterpret_cast(&sv), sizeof(SinhVien))) {
if (strcmp(sv.mssv, mssv) != 0) {
tempFile.write(reinterpret_cast(&sv),sizeof(SinhVien)); } }
• Sau khi lặp qua toàn bộ file SV.BIN, đóng cả hai file inFile và tempFile.
• Đổi tên file temp.BIN thành SV.BIN bằng cách sử dụng: rename("temp.BIN", "SV.BIN")}
Xóa dữ liệu trong file HOCPHAN.BIN void xoaHocPhan Đầu vào: mahp
Đầu ra: dữ liệu đã được xóa
• Mở file nhị phân HP.BIN: ifstream inFile("HP.BIN", ios::binary);
• Mở file temp.BIN để tạo một file tạm để sao chép thông tin sinh viên không bị xóa:
ofstream tempFile("temp.BIN", ios::binary);
• Lặp qua từng bản ghi trong file HP.BIN bằng cách sử dụng vòng lặp while.
▪ Trong mỗi lần lặp, đọc một bản ghi từ file HP.BIN và kiểm tra mã học phần của bản ghi đó.
▪ Nếu mã học phần không trùng khớp với mã học phần cần xóa, sao chép bản ghi đó vào file
tạm temp.BIN bằng cách sử dụng tempFile.write().
while (inFile.read(reinterpret_cast(&hp), sizeof(HocPhan))) {
if (strcmp(sv.mahp, hp) != 0) {
tempFile.write(reinterpret_cast(&hp),sizeof(HocPhan)); } }
• Sau khi lặp qua toàn bộ file HP.BIN, đóng cả hai file inFile và tempFile.
• Đổi tên file temp.BIN thành HP.BIN bằng cách sử dụng: rename("temp.BIN", "HP.BIN")} lOMoAR cPSD| 61570513 Xóa điểm thi void xoaDiemThi Đầu vào: mahp, mssv
Đầu ra: dữ liệu đã được xóa
• Mở file nhị phân DIEMTHI.BIN:
ifstream inFile("DIEMTHI.BIN", ios::binary);
• Mở file temp.BIN để tạo một file tạm để sao chép thông tin sinh viên không bị xóa:
ofstream tempFile("temp.BIN", ios::binary);
• Lặp qua từng bản ghi trong file DIEMTHI.BIN bằng cách sử dụng vòng lặp while.
▪ Trong mỗi lần lặp, đọc một bản ghi từ file DIEMTHI.BIN và kiểm tra mã học phần của bản ghi đó.
▪ Nếu mã học phần không trùng khớp với mã học phần cần xóa, sao chép bản ghi đó vào file
tạm temp.BIN bằng cách sử dụng tempFile.write().
while (inFile.read(reinterpret_cast(&dt), sizeof(DiemThi))) {
if (strcmp(dt.mahp, mahp) != 0 || strcmp(dt.mssv, mssv) != 0) {
tempFile.write(reinterpret_cast(&hp),sizeof(HocPhan)); } }
• Sau khi lặp qua toàn bộ file DIEMTHI.BIN, đóng cả hai file inFile và tempFile.
• Đổi tên file temp.BIN thành DIEM.BIN bằng cách sử dụng:
rename("temp.BIN", "DIEMTHI.BIN")}
Bước 7: Sửa dữ liệu
Sửa dữ liệu file SV.BIN
void suaSinhVien(const char* mssv) Đầu vào: mssv
Đầu ra: Dữ liệu đã được sửa
• Mở file SV.BIN trong chế độ đọc và ghi nhị phân: fstream (ios::binary|ios::in | ios::out)
• Lặp qua từng bản ghi trong file SV.BIN bằng cách sử dụng vòng lặp while.
while (file.read(reinterpret_cast(&sv), sizeof(SinhVien))) {
if (strcmp(sv.mssv ,mssv) == 0) { SinhVien sv ;
file.seekp(-static_cast(sizeof(SinhVien)), ios::cur); lOMoAR cPSD| 61570513
file.write(reinterpret_cast(&sv), sizeof(SinhVien)); file.close(); return; }
• Nếu không tìm thấy bản ghi nào có mã số sinh viên trùng khớp, đóng file SV.BIN. Sửa dữ liệu file HP.BIN void suaHocPhan Đầu vào: mahp
Đầu ra: Dữ liệu đã được sửa
• Mở file HP.BIN trong chế độ đọc và ghi nhị phân: fstream (ios::binary|ios::in | ios::out)
• Lặp qua từng bản ghi trong file HP.BIN bằng cách sử dụng vòng lặp while.
while (file.read(reinterpret_cast(&hp), sizeof(HocPhan))) {
if (strcmp(hp.mahp,mahp) == 0) { HocPhan hp ;
file.seekp(-static_cast(sizeof(HocPhan)), ios::cur);
file.write(reinterpret_cast(&hp), sizeof(SinhVien)); file.close(); return; }
• Nếu không tìm thấy bản ghi nào có mã học phần trùng khớp, đóng file HP.BIN. Sửa dữ liệu file
DIEMTHI.BIN void suaDiemThi Đầu vào: mahp , mssv
Đầu ra: Dữ liệu đã được sửa
• Mở file DIEMTHI.BIN trong chế độ đọc và ghi nhị phân:
fstream (ios::binary|ios::in | ios::out)
• Lặp qua từng bản ghi trong file DIEMTHI.BIN bằng cách sử dụng vòng lặp while. while
(file.read(reinterpret_cast(&dt), sizeof(DiemThi)){ if
(strcmp(dt.mahp, mahp) == 0 && strcmp(dt.mssv, mssv) == 0) { DiemThi
dt; file.seekp(-static_cast(sizeof(DiemThi)), ios::cur);
file.write(reinterpret_cast(&dt), sizeof(DiemThi)); file.close(); lOMoAR cPSD| 61570513 return; }
• Nếu không tìm thấy bản ghi nào có mã học phần và mã số sinh viên trùng khớp, đóng file DIEMTHI.BIN.
Bước 7: Tính điểm trung bình tích lũy của sinh viên Chuyển
đổi từ thang 10 sang thang 4:
float tinhDiemThangDiem4(float diem) {
if (diem >= 8.5 && diem <= 10)
return 4.0; else if (diem >= 8.0 &&
diem <= 8.4) return 3.5; else
if (diem >= 7.0 && diem <= 7.9)
return 3.0; else if (diem >= 6.5 &&
diem <= 6.9) return 2.5; else
if (diem >= 5.5 && diem <= 6.4)
return 2.0; else if (diem >= 5.0 &&
diem <= 5.4) return 1.5; else
if (diem >= 4.0 && diem <= 4.9) return 1.0; else return 0.0; }
Tính điểm trung bình sinh viên float tinhGPA(const char* mssv)
{ ifstream inFile("DIEMTHI.BIN", ios::binary); if
(!inFile) { cout << "Khong the doc file DIEMTHI.BIN" << endl; return 0.0f; }
DiemThi dt; float tongDiem = 0.0f; int tongSoTC = 0;
while (inFile.read(reinterpret_cast(&dt),sizeof(DiemThi))){
if (strcmp(dt.mssv, mssv) != 0) { continue; }
HocPhan hp; ifstream hpFile("HP.BIN", ios::binary);
while (hpFile.read(reinterpret_cast(&hp), sizeof(HocPhan))) {
if (strcmp(dt.mahp, hp.mahp) == 0) { tongSoTC += hp.so_tc; break; lOMoAR cPSD| 61570513 } } hpFile.close();
float diem4 = tinhDiemThangDiem4(dt.diem); tongDiem += diem4 * hp.so_tc;
} inFile.close(); if (tongSoTC == 0) { cout <<
"Khong tim thay sinh vien co MSSV la: " << mssv << endl; return 0.0f; } float gpa = tongDiem / tongSoTC; gpa = roundf(gpa * 100) / 100; return gpa; }
Ghi điểm trung bình tích lũy vào file GPA.BIN void ghiGPA(const
char* mssv, const float gpa) { ofstream
outFile("GPA.BIN", ios::binary | ios::app); if
(!outFile) { cout << "Khong the ghi file GPA.BIN" << endl; return;
} outFile.write(reinterpret_cast(mssv), strlen(mssv)
+ 1); outFile.write(reinterpret_cast(&gpa),
sizeof(float)); outFile.close(); }
Bước 8: hiển thị Tên học phần và danh sách gồm mã số, họ tên sinh viên và điểm học phần này của các sinh viên Đầu vào: mã học phần
Đầu ra: mã số sinh viên, họ đệm, tên sinh viên, điểm học phần của sinh viên void
hien_thi_sv_theo_hp(const char* mahp) { ifstream inFile("DIEMTHI.BIN",
ios::binary); DiemThi dt; bool found = false; while
(inFile.read(reinterpret_cast(&dt), sizeof(DiemThi))) { if
(strcmp(dt.mahp, mahp) == 0) { ifstream svFile("SV.BIN",
ios::binary); SinhVien sv; while
(svFile.read(reinterpret_cast(&sv), sizeof(SinhVien)))
{ if (strcmp(sv.mssv ,dt.mssv)
==0) { cout << "Ma SV: " << sv.mssv <<
endl; cout << "Ho dem: " << sv.hodem <<
endl; cout << "Ten: " << sv.ten_sv << lOMoAR cPSD| 61570513
endl; cout << "Diem: " << dt.diem << endl; cout << endl; } } svFile.close() ; found = true;
} } inFile.close(); if (!found) { cout << "Khong
tim thay thong tin diem thi cho hoc phan nay." << endl; } }
Bước 9: hiển thị danh sách gồm mã số, họ tên của những sinh viên không đạt học phần này (điểm <4) Đầu vào: mã học phần
Đầu ra: mã số sinh viên, họ đệm, tên sinh viên không đạt học phần void
hien_thi_sinh_vien_khong_dat_hp(const char* mahp) { ifstream
inFile("DIEMTHI.BIN", ios::binary); DiemThi dt; bool found = false; while
(inFile.read(reinterpret_cast(&dt),
sizeof(DiemThi))) { if (strcmp(dt.mahp, mahp) == 0) {
ifstream svFile("SV.BIN", ios::binary); SinhVien sv; while
(svFile.read(reinterpret_cast(&sv),
sizeof(SinhVien))) { if (strcmp(dt.mssv, sv.mssv) == 0)
{ if (dt.diem <= 4) { cout <<
"Ma SV: " << sv.mssv << endl; cout << "Ho dem: "
<< sv.hodem << endl; cout << "Ten: " << sv.ten_sv
<< endl; cout << "Diem: " << dt.diem << endl;
cout << endl; found = true; } } } svFile.close();
} } inFile.close(); if (!found) { cout << "Khong
tim thay thong tin diem thi cho hoc phan nay." << endl; } }
Bước 10: hiển thị danh sách các học phần mà sinh viên này chưa đạt
Đầu vào: mã số sinh viên lOMoAR cPSD| 61570513
Đầu ra: học phần sinh viên chưa đạt void
hien_thi_hoc_phan_chua_dat() { char mssv[10] ;
cout << "Nhap ma so sinh vien " << endl ; cin
>> mssv ; ifstream FileDiem("DIEMTHI.BIN",
ios::binary); ifstream FileHocPhan("HP.BIN", ios::binary);
if (!FileDiem || !FileHocPhan) { cout << "Khong the doc
file DIEMTHI.BIN hoac HP.BIN" << endl; return; }
DiemThi dt; HocPhan hp; bool found = false; cout << "Danh
sach hoc phan chua dat cua sinh vien ma SV: " << mssv << endl;
while (FileDiem.read(reinterpret_cast(&dt), sizeof(DiemThi))) {
if (strcmp(dt.mssv, mssv) == 0 && dt.diem < 4.0f) { while
(FileHocPhan.read(reinterpret_cast(&hp),
sizeof(HocPhan))) { if (strcmp(dt.mahp, hp.mahp) == 0) {
cout << "Ma HP: " << hp.mahp << endl; cout << "Ten
mon hoc: " << hp.ten_mon_hoc << endl; cout << "So tin
chi: " << hp.so_tc << endl; cout << "Diem: " <<
dt.diem << endl; cout << endl; found = true; break; } } FileHocPhan.clear();
FileHocPhan.seekg(0, std::ios::beg); } }
FileDiem.close(); FileHocPhan.close(); if (!found) {
cout << "Khong co hoc phan nao chua dat cho sinh vien ma SV: " << mssv << std::endl; } }
Bước 11: hiển thị điểm trung bình chung tích lũy của sinh viên
Đầu vào: mã số sinh viên
Đầu ra: điểm trung bình tích lũy của sinh viên lOMoAR cPSD| 61570513
void hienThiGPA(const char* mssv) { ofstream
outputFile("output.txt", ios::app); float gpa; if
(tinhGPA(mssv)) { gpa = tinhGPA(mssv); if
(outputFile.is_open()) { outputFile << "Ma so
sinh vien: " << mssv << endl; outputFile << "Diem
trung binh tich luy: " << gpa << endl;
} else{ outputFile <<"Khong the mo file output.txt" << endl;
} } else { cout << "Ma so sinh vien
khong ton tai." << endl; } } lOMoAR cPSD| 61570513 3. Mã nguồn: #include #include #include #include #include #include using namespace std; struct SinhVien{ char mssv[10]; char hodem[50] ; char ten_sv[50]; char gioi_tinh[10]; char ngay_sinh[11]; }; struct HocPhan{ char mahp[10] ; char ten_mon_hoc[50]; int so_tc; }; struct DiemThi{ char mahp[10]; char mssv[10]; float diem;
}; bool KiemTraNgaySinh(const char* ngay_sinh) { if (strlen(ngay_sinh) !=
10) { cout << "Dinh dang ngay sinh khong hop le! Vui long nhap lai." << endl; return false;
} int ngay, thang, nam; if (sscanf(ngay_sinh, "%d/%d/%d", &ngay,
&thang, &nam) != 3) { cout << "Dinh dang ngay sinh khong hop le! Vui
long nhap lai." << endl; return false;
} if (thang < 1 || thang > 12 || ngay < 1 || ngay > 31 || nam < 1900)
{ cout << "Ngay sinh khong hop le! Vui long nhap lai." << endl; return false;
} else if ((thang == 4 || thang == 6 || thang == 9 || thang == 11) && ngay >
