Bài tập struct trong C/C++

Bài tập struct trong C/C++ có lời giải

Trước khi đi vào bài tập struct trong C/C++, LTKK muốn tóm tắt về kiểu cấu trúc trong C. Kiểu cấu trúc (structure) trong C/C++ là 1 kiểu dữ liệu người dùng tự định nghĩa dựa trên các kiểu dữ liệu có sẵn (int, char*, float, …). Chúng ta thường dùng kiểu cấu trúc này để định nghĩa các đối tượng. Ví dụ:

  • Đối tượng Sinh Viên: mã sinh viên (char*), tên sinh viên (char*), năm sinh (int), …
  • Đối tượng Date: ngày (int), tháng (int), năm (int).
  • Đối tượng Sách: mã sách (char*), tên sách (char*), tác giả (char*), số lượng (int), ngày xuất bản (Date), …

LTKK đã có 1 bài viết riêng hướng dẫn về kiểu cấu trúc trong C/C++. Bạn nên có kiến thức về Struct trong C trước khi thực hành bài tập struct tại bài viết này.

Bài tập struct trong C/C++

Kiểu cấu trúc (struct) là của ngôn ngữ lập trình C, do đó chúng ta có thể sử dụng nó ở trong C++. Trong mục bài tập này, mình sẽ cố gắng chỉ sử dụng ngôn ngữ C. Nếu có phần nào trong source code sử dụng C++, mình sẽ trình bày rõ.

# Bài tập phân số

Đề bài: Định nghĩa kiểu cấu trúc phân số gồm tử số và mẫu số. Thực hiện cài đặt các chức năng sau:

  • Cài đặt các phép toán cộng, trừ, nhân, chia 2 phân số.
  • In ra kết quả các phép toán kể trên dưới dạng phân số tối giản.

Lời giải:

Dưới đây là lời giải tham khảo sử dụng ngôn ngữ C.

#include <stdio.h>
#include <string.h>
#include <math.h>
 
int UCLN(int a, int b)
{
    a = abs(a);
    b = abs(b);
    while (a * b != 0)
    {
        if (a > b)
            a %= b;
        else
            b %= a;
    }
    return a + b;
}
 
int BSCNN(int a, int b)
{
    return a * b / UCLN(a, b);
}
 
typedef struct PhanSo
{
    int tuso, mauso;
} PS;
 
PS rutGon(PS a)
{
    PS c;
    c.tuso = a.tuso / UCLN(a.tuso, a.mauso);
    c.mauso = a.mauso / UCLN(a.tuso, a.mauso);
    return c;
}
 
PS cong(PS a, PS b)
{
    PS c;
    c.tuso = a.tuso * b.mauso + a.mauso * b.tuso;
    c.mauso = a.mauso * b.mauso;
    c = rutGon(c);
    return c;
}
 
PS tru(PS a, PS b)
{
    PS c;
    c.tuso = a.tuso * b.mauso - a.mauso * b.tuso;
    c.mauso = a.mauso * b.mauso;
    c = rutGon(c);
    return c;
}
 
PS nhan(PS a, PS b)
{
    PS c;
    c.tuso = a.tuso * b.tuso;
    c.mauso = a.mauso * b.mauso;
    c = rutGon(c);
    return c;
}
 
PS chia(PS a, PS b)
{
    PS c;
    c.tuso = a.tuso * b.mauso;
    c.mauso = a.mauso * b.tuso;
    c = rutGon(c);
    return c;
}
void print(PS a)
{
    printf("%d/%d", a.tuso, a.mauso);
}
int main()
{
    PS a, b, c;
    printf("\nNhap phan so a : ");
    scanf("%d%d", &a.tuso, &a.mauso);
    printf("\nNhap phan so b : ");
    scanf("%d%d", &b.tuso, &b.mauso);
    printf("\nToi gian a ta duoc : ");
    a = rutGon(a);
    print(a);
    printf("\nToi gian b ta duoc : ");
    b = rutGon(b);
    print(b);
    printf("\nTong cua hai phan so = ");
    c = cong(a, b);
    print(c);
    printf("\nHieu cua hai phan so = ");
    c = tru(a, b);
    print(c);
    printf("\nTich cua hai phan so = ");
    c = nhan(a, b);
    print(c);
    printf("\nThuong cua hai phan so = ");
    c = chia(a, b);
    print(c);
}

Kết quả chạy chương trình:

Nhap phan so a : 1 2

Nhap phan so b : 3 4

Toi gian a ta duoc : 1/2
Toi gian b ta duoc : 3/4
Tong cua hai phan so = 5/4
Hieu cua hai phan so = -1/4
Tich cua hai phan so = 3/8
Thuong cua hai phan so = 2/3

# Bài tập quản lý sinh viên

Mục tiêu của bài tập này là sử dụng cấu trúc struct lồng nhau.

Đề bài: Viết chương trình định nghĩa kiểu cấu trúc NGAYTHANG bao gồm 3 thuộc tính (ngày, tháng, năm). Dựa trên kiểu cấu trúc NGAYTHANG đã có, tiếp tục định nghĩa kiểu câu trúc SinhVien bao gồm các thông tin (mã sinh viên, họ đệm, tên, ngày tháng năm sinh, giới tính, hộ khẩu thường trú, điểm thi đại học). Viết các hàm con thực hiện các chức năng sau đây:

  • Nhập danh sách sinh viên từ bàn phím.
  • Hiển thị danh sách sinh viên đã nhập.
  • Sắp xếp danh sách sinh viên theo điểm tăng dần.
  • Hiển thị danh sách sau khi sắp xếp.

Viết hàm main thực hiện các chức năng kể trên.

Lời giải tham khảo:

  • Lời giải này có sử dụng C++ ở hàm nhập/xuất: cin, cout; cấp phát động trong C++ (toán tử new, delete).
  • Khi dùng struct trong C++, chúng ta không cần thêm tiền tố struct khi khai báo biến. Do đó, không cần dùng từ khóa typedef để đặt lại tên kiểu cấu trúc sinh viên.
#include<iostream>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<limits>

using namespace std;
 
struct NGAYTHANG {
    int ngay;
    int thang;
    int nam;
};
struct SV {
    char masv[12];
    char hodem[30];
    char ten[10];
    NGAYTHANG ngsinh;
    char gioitinh[4];
    char hokhau[20];
    float diem;
};
void Nhapsv(SV *sv) {
    cin.ignore(256, '\n');
    cout << "\tMa sv: ";
    scanf(" %[^\n]s", sv->masv);
    cout << "\tHo dem: ";
    scanf(" %[^\n]s", sv->hodem);
    cout << "\tTen: ";
    scanf(" %[^\n]s", sv->ten);
    cout << "\tNgay sinh: ";
    cin >> sv->ngsinh.ngay;
    cout << "\tThang sinh: ";
    cin >> sv->ngsinh.thang;
    cout << "\tNam sinh: ";
    cin >> sv->ngsinh.nam;
    cout << "\tGioi tinh: ";
    scanf(" %[^\n]s", sv->gioitinh);
    cout << "\tHo khau: ";
    scanf(" %[^\n]s", sv->hokhau);
    cout << "\tDiem: ";
    cin >> sv->diem;
}
void Hienthisv(SV *sv) {
    cout << sv->masv;
    cout << "\t" << sv->hodem;
    cout << " " << sv->ten;
    cout << "\t" << sv->ngsinh.ngay;
    cout << "-" << sv->ngsinh.thang;
    cout << "-" << sv->ngsinh.nam;
    cout << "\t" << sv->gioitinh;
    cout << "\t" << sv->hokhau;
    cout << "\t" << sv->diem;
}
void Nhapds(SV *p, int n) {
    for (int i = 0; i < n; i++) {
        cout << "Nhap thong tin cua sv thu " << i + 1 << " :" << endl;
        Nhapsv(p + i);
    }
}
void Hienthids(SV *p, int n) {
    for (int i = 0; i < n; i++) {
        Hienthisv(p + i);
        cout << "\n";
    }
}
void Sapxep(SV *p, int n) {
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++)
            if ((p + i)->diem > (p + j)->diem) {
                SV tmp = * (p + j);
                *(p + j) = * (p + i);
                *(p + i) = tmp;
            }
    }
}
int main() {
    SV *p;
    int n;
    do {
        cout << "Nhap vao so sv: ";
        cin >> n;
    }
    while (n < 0 || n > 10);
    p = new SV[n];
    cout << "Nhap vao thong tin " << n << " sv: " << endl;
    Nhapds(p, n);
    cout << "Hien thi thong tin vua nhap: " << endl;
    Hienthids(p, n);
    cout << "\nDanh sach sau khi sap xep la: " << endl;
    Sapxep(p, n);
    Hienthids(p, n);
    delete p;
    return 0;
}

Kết quả chạy chương trình:

Nhap vao so sv: 2
Nhap vao thong tin 2 sv: 
Nhap thong tin cua sv thu 1 :
        Ma sv: sv001
        Ho dem: Nguyen Van
        Ten: Hieu
        Ngay sinh: 10
        Thang sinh: 10
        Nam sinh: 1996
        Gioi tinh: Nam
        Ho khau: Ha Noi
        Diem: 10
Nhap thong tin cua sv thu 2 :
        Ma sv: sv002 
        Ho dem: Nguyen Thi
        Ten: Mai
        Ngay sinh: 11
        Thang sinh: 11
        Nam sinh: 1996
        Gioi tinh: Nu
        Ho khau: Nam Dinh
        Diem: 9
Hien thi thong tin vua nhap: 
sv001   Nguyen Van Hieu 10-10-1996      Nam     Ha Noi  10
sv002    Nguyen Thi Mai  11-11-1996      Nu      Nam Dinh        9

Danh sach sau khi sap xep la: 
sv002    Nguyen Thi Mai  11-11-1996      Nu      Nam Dinh        9
sv001   Nguyen Van Hieu 10-10-1996      Nam     Ha Noi  10

# Bài tập struct quản lý món ăn

Đề bài: Viết chương trình tổ chức dữ liệu quản lý các món ăn, mỗi món ăn bao gồm các thông tin sau: tên món ăn, đơn giá, đơn vị tính, loại món, …

Viết các chương trình con (hàm) thực hiện lần lượt các yêu cầu sau đây:

  • Nhập danh sách n món ăn từ bàn phím.
  • Hiển thị danh sách món ăn vừa nhập.
  • Thực hiện sắp xếp danh sách món ăn tăng dần/ giảm dần theo 1 tiêu chí nào đó (tự lựa chọn).
  • Thực hiện tìm kiếm món ăn theo tiêu chí tùy ý.
  • Ghi danh sách món ăn vào tập tin.
  • Đọc dữ liệu món ăn từ tập tin.
  • Trích lọc thông tin món ăn theo 1 tiêu chí tùy chọn và xuất kết quả ra tệp tin.

Cài đặt chương trình chính triển khai lần lượt các chức năng kể trên.

Lời giải tham khảo:

#include <stdio.h> // thư viện nhập xuất chuẩn (scanf, printf, fgets, ...)
#include <string.h> // thư viện chuỗi (strlen, strcmp, ...)
#include <stdlib.h> // dùng hàm exit và hằng số EXIT_FAILURE, EXIT_SUCCESS

// Hằng số số lượng phần tử tối đa món ăn có thể lưu
#define MAX_SIZE 100

// 2 hằng số đường dẫn file dùng cho đọc/ghi file và trích xuất thông tin
const char* DATA_PATH = "data.dat";
const char* EXTRACT_PATH = "trichloc.dat";

struct Food {
    char name[50]; // tên món ăn
    int price; // đơn giá
    char unit[50]; // đơn vị tính
    char type[50]; // loại món
};

// Thay vì khai báo struct Food <tên biến> thì chỉ cần Food <tên biến>
// ngắn gọn hơn
typedef struct Food Food;

// Hàm nhập 1 món ăn
Food createFood(){
    Food food;
    char temp[50];
    printf("Enter food name: ");
    scanf(" %[^\n]s", food.name);
    printf("Enter food price: ");
    scanf(" %[^\n]s", temp);
    food.price = atoi(temp);
    printf("Enter food unit: ");
    scanf(" %[^\n]s", food.unit);
    printf("Enter food type: ");
    scanf(" %[^\n]s", food.type);
    return food;
}

// Hàm nhập n món ăn
void createFoods(Food arr[], int n){
    for (int i = 0; i < n; i++){
        Food food = createFood();
        arr[i] = food;
        printf("-----------------\n");
    }
}

// Hàm in tiêu đề, phục vụ in thông tin món ăn dạng bảng (table)
void printTitle(){
    printf("%20s%20s%20s%20s\n", "Name", "Price", "Unit", "Type");
}

// Hàm in thông tin 1 món ăn
void printFood(Food food){
    printf("%20s%20d%20s%20s\n", food.name, food.price, food.unit, food.type);
}

// Hàm in ra màn hình ds món ăn
void printFoods(Food arr[], int n){
    printTitle();
    for (int i = 0; i < n; i++){
        printFood(arr[i]);
    }
}

// Hàm sắp xếp ds món ăn
// Có thể sắp xếp theo tên món hoặc giá tăng dần
void sortFood(Food arr[], int n){
    int choice;
    printf("Choose sort type:\n1. By name\n2. By price\nEnter your choice: ");
    scanf("%d", &choice);
    if (choice != 1 && choice != 2){
        printf("Only option 1 or 2 is allow!");
        return;
    }
    for (int i = 0; i < n; i++){
        for(int j = i+1; j < n; j++){
            if ((choice == 1 && strcmp(arr[i].name, arr[j].name) > 0) || 
            (choice == 2 && arr[i].price > arr[j].price)) {
                Food temp = arr[i];
                arr[i] = arr[j];
                arr[j] = temp;
            }
        }
    }
}

// Hàm tìm kiếm món ăn
// Có thể chọn tìm theo tên hoặc theo loại món ăn
void searchFood(Food arr[], int n){
    int choice;
    printf("Choose search type:\n1. By name\n2. By type\nEnter your choice: ");
    scanf("%d", &choice);
    if (choice != 1 && choice != 2){
        printf("Only option 1 or 2 is allow!");
        return;
    }
    char keyword[50];
    printf("Enter the search keyword: ");
    scanf(" %[^\n]s", keyword);
    printf("Search result for keyword '%s':\n", keyword);
    int count = 0; // đếm số lượng kết quả tìm được
    for (int i = 0; i < n; i++){
        if ((choice == 0 && strcmp(keyword, arr[i].name) == 1) || (choice == 2 && strcmp(keyword, arr[i].type) == 0)) {
            if (count == 0){
                printTitle();
            }
            printFood(arr[i]);
            count++;
        }
    }
    // Nếu không tìm được kết quả nào thì thông báo ko thấy
    if (count == 0){
        printf("No result!\n");
    }
}

// Hàm ghi các món ăn ra file
void toFile(Food arr[], int n){
    FILE *fptr; // con trỏ file
    fptr = fopen(DATA_PATH,"w"); // mở file
    if(fptr == NULL) {
      printf("Error on open file for write!");   
      exit(EXIT_FAILURE);             // thoát chương trình nếu có lỗi mở file
   }
    fprintf(fptr,"%d\n", n); // dòng đầu tiên ghi số món ăn
    for (int i = 0; i < n; i++){
        // một món ăn sẽ ghi 4 dòng
        fprintf(fptr, "%s\n%d\n%s\n%s\n", arr[i].name, arr[i].price, arr[i].unit, arr[i].type);
    }
    printf("Write %d foods to path %s successed!\n", n, DATA_PATH);
    fclose(fptr); // đóng file
}

// Hàm đọc món ăn từ file
// n là tham chiếu, vì ta cần thay đổi giá trị của n ở hàm main tại hàm này.
// Nếu dùng C thì có thể dùng con trỏ thay thế
void fromFile(Food arr[], int &n){
    FILE *fptr;
    fptr = fopen(DATA_PATH,"r");
    if(fptr == NULL) {
      printf("Error on open file for read!\n");   
      exit(EXIT_FAILURE);             // thoát chương trình nếu có lỗi mở file
   }
   fgets(arr[0].name, 50, fptr); // đọc 1 dòng
   n = atoi(arr[0].name); // chuyển chuỗi về số, dòng đầu tiên là số lượng món ăn.
   // Kiểm tra số món ăn trong file ko đc vượt qua MAX_SIZE, cũng ko được âm
   if (n < 0 || n > MAX_SIZE){
       printf("Number of foods not valid!");
       exit(EXIT_FAILURE);
   }
   for (int i = 0; i < n; i++){
       // đọc 4 dòng để lấy thông tin 1 món ăn
       fgets(arr[i].name, 50, fptr);
       arr[i].name[strcspn(arr[i].name, "\n")] = 0; // xóa \n ở cuối
       fgets(arr[i].unit, 50, fptr);
       arr[i].price = atoi(arr[i].unit); // chuyển chuỗi về số
       fgets(arr[i].unit, 50, fptr);
       arr[i].unit[strcspn(arr[i].unit, "\n")] = 0;
       fgets(arr[i].type, 50, fptr);
       arr[i].type[strcspn(arr[i].type, "\n")] = 0;
   }
   printf("Read %d foods from path %s successed!\n", n, DATA_PATH);
    fclose(fptr);
}

// Trích xuất các món ăn có giá nằm trong phạm vi x - y
void filterFood(Food arr[], int n){
    int minPrice, maxPrice;
    printf("Enter min price: "); scanf("%d", &minPrice);
    printf("Enter max price: "); scanf("%d", &maxPrice);
    // Nếu giới hạn dưới mà lớn hơn, thì hoán đổi
    if (minPrice > maxPrice) {
        int temp = minPrice;
        minPrice = maxPrice;
        maxPrice = temp;
    }
    // Mở file để ghi
    FILE *fptr; // con trỏ file
    fptr = fopen(EXTRACT_PATH,"w"); // mở file
    if(fptr == NULL) {
      printf("Error on open file for write!");   
      exit(EXIT_FAILURE);             // thoát chương trình nếu có lỗi mở file
   }
    int count = 0; // đếm số lượng kết quả tìm được
    for (int i = 0; i < n; i++){
        if (arr[i].price >= minPrice && arr[i].price <= maxPrice) {
            // Ghi tiêu đề
            if (count == 0){
                fprintf(fptr, "%20s%20s%20s%20s\n", "Name", "Price", "Unit", "Type");
            }
            // ghi mỗi món trên 1 dòng
            fprintf(fptr, "%20s%20d%20s%20s\n", arr[i].name, arr[i].price, arr[i].unit, arr[i].type);
            count++;
        }
    }
    if (count == 0){
        fprintf(fptr, "%s", "No result!\n");
    }
    printf("Found %d result in price range %d to %d!\n", count, minPrice, maxPrice);
    fclose(fptr);
}

void printMenu(){
    printf("=================== MENU ======================\n");
    printf("1. Create foods from keyboard\n");
    printf("2. Show foods\n");
    printf("3. Sort foods\n");
    printf("4. Search foods\n");
    printf("5. Write to file\n");
    printf("6. Read from file\n");
    printf("7. Filter & extract foods\n");
    printf("8. Exit\nYour choice: ");
}

int main(){
    Food foods[MAX_SIZE];
    int n = 0, choice;
    while (1){
        printMenu();
        scanf("%d", &choice);
        if (choice < 1 || choice > 8){
            printf("Please choose one option from 1 - 8!");
            continue;
        }
        switch (choice)
        {
        case 1:
            do {
                printf("Enter number of foods: ");
                scanf("%d", &n); 
                }while (n <= 0 || n > MAX_SIZE);
                createFoods(foods, n);
            break;
        case 2:
            if (n == 0){
                printf("No data!\n");
                continue;
            }
            printFoods(foods, n);
            break;
        case 3:
            if (n == 0){
                printf("No data!\n");
                continue;
            }
            sortFood(foods, n);
            printf("Foods after sorted:\n");
            printFoods(foods, n);
            break;
        case 4:
            if (n == 0){
                printf("No data!\n");
                continue;
            }
            searchFood(foods, n);
            break;
        case 5:
            if (n == 0){
                printf("No data!\n");
                continue;
            }
            toFile(foods, n);
            break;
        case 6:
            fromFile(foods, n);
            break;
        case 7:
            if (n == 0){
                printf("No data!\n");
                continue;
            }
            filterFood(foods, n);
            break;
        case 8:
            printf("Good bye!\n");
            exit(EXIT_SUCCESS);
        }
    }
    
}

Kết quả chạy chương trình:

=================== MENU ======================
1. Create foods from keyboard
2. Show foods
3. Sort foods
4. Search foods
5. Write to file
6. Read from file
7. Filter & extract foods
8. Exit
Your choice: 1
Enter number of foods: 3
Enter food name: 3
Enter food price: 3
Enter food unit: 3
Enter food type: 3
-----------------
Enter food name: 1
Enter food price: 1
Enter food unit: 1
Enter food type: 1
-----------------
Enter food name: 2
Enter food price: 2
Enter food unit: 2
Enter food type: 2
-----------------
=================== MENU ======================
1. Create foods from keyboard
2. Show foods
3. Sort foods
4. Search foods
5. Write to file
6. Read from file
7. Filter & extract foods
8. Exit
Your choice: 2
                Name               Price                Unit                Type
1.                      3                   3                   3                   3
2.                      1                   1                   1                   1
3.                      2                   2                   2                   2
=================== MENU ======================
1. Create foods from keyboard
2. Show foods
3. Sort foods
4. Search foods
5. Write to file
6. Read from file
7. Filter & extract foods
8. Exit
Your choice: 3
Choose sort type:
1. By name
2. By price
Enter your choice: 1
Foods after sorted:
                Name               Price                Unit                Type
1.                      1                   1                   1                   1
2.                      2                   2                   2                   2
3.                      3                   3                   3                   3
=================== MENU ======================
1. Create foods from keyboard
2. Show foods
3. Sort foods
4. Search foods
5. Write to file
6. Read from file
7. Filter & extract foods
8. Exit
Your choice: 4
Choose search type:
1. By name
2. By type
Enter your choice: 2
Enter the search keyword: 2
Search result for keyword '2':
                Name               Price                Unit                Type
                     2                   2                   2                   2
=================== MENU ======================
1. Create foods from keyboard
2. Show foods
3. Sort foods
4. Search foods
5. Write to file
6. Read from file
7. Filter & extract foods
8. Exit
Your choice: 5
Write 3 foods to path data.dat successed!
=================== MENU ======================
1. Create foods from keyboard
2. Show foods
3. Sort foods
4. Search foods
5. Write to file
6. Read from file
7. Filter & extract foods
8. Exit
Your choice: 6
Read 3 foods from path data.dat successed!
=================== MENU ======================
1. Create foods from keyboard
2. Show foods
3. Sort foods
4. Search foods
5. Write to file
6. Read from file
7. Filter & extract foods
8. Exit
Your choice: 2
                Name               Price                Unit                Type
1.                      1                   1                   1                   1
2.                      2                   2                   2                   2
3.                      3                   3                   3                   3
=================== MENU ======================
1. Create foods from keyboard
2. Show foods
3. Sort foods
4. Search foods
5. Write to file
6. Read from file
7. Filter & extract foods
8. Exit
Your choice: 7
Enter min price: 2
Enter max price: 3
Found 2 result in price range 2 to 3!
=================== MENU ======================
1. Create foods from keyboard
2. Show foods
3. Sort foods
4. Search foods
5. Write to file
6. Read from file
7. Filter & extract foods
8. Exit
Your choice: 8
Good bye!

# Bài tập quản lý sách

Viết chương trình quản lý sách của một nhà xuất bản với thông tin của mỗi cuốn sách bao gồm: mã sách, tên sách, tác giả, nhà xuất bản, năm xuất bản, đơn giá, số lượng, thuế, thực tiền. Trong đó thành tiền và thực tiền được tính dựa trên các thông tin khác được nhập từ bàn phím. Viết chương trình con triển khai các chức năng sau:

  1. Nhập thông tin các cuốn sách từ bàn phím.
  2. In danh sách thông tin các cuốn sách.
  3. Tính cột thành tiền theo công thức thành tiền = số lượng * đơn giá.
  4. Tính cột thực tiền = thành tiền + thuế VAT
  5. Sắp xếp các cuốn sách theo thứ tự giảm dần về năm xuất bản.
  6.  In thông tin các cuốn sách có thực tiền lớn nhất.
  7. In thông tin tổng số lượng các cuốn sách.
  8. In danh sách các cuốn sách có thuế VAT lớn hơn 1 giá trị được nhập từ bàn phím.
  9. Lưu danh sách các cuốn sách đã nhập vào tập tin.
  10. Đọc danh sách các cuốn sách từ tập tin và hiển thị lên màn hình.

Dưới đây là lời giải tham khảo sử dụng ngôn ngữ C++.

#include <iostream>
#include <string.h>
#include <iomanip>
#include <stdlib.h>
using namespace std;

const int MAX_SIZE = 100; // số lượng phần tử tối đa của mảng
const char* DATA_PATH = "books.dat"; // đường dẫn tới file dữ liệu dùng đọc/ ghi

// Định nghĩa kiểu sách
struct Book {
    char maBook[50];
    char tenBook[50];
    char tacGia[50];
    char nhaXB[50];
    int namXB;
    float donGia;
    int soLuong;
    float thanhTien;
    float thueVAT;
    float thucTien;
};
typedef struct Book Book;

// Hàm nhập 1 cuốn sách
Book NhapBook(){
    Book book;
    cin.ignore();
    cout << "Nhap ma book: "; cin.getline(book.maBook, 50);
    cout << "Nhap ten book: "; cin.getline(book.tenBook, 50);
    cout << "Nhap ten TG: "; cin.getline(book.tacGia, 50);
    cout << "Nhap nha XB: "; cin.getline(book.nhaXB, 50);
    cout << "Nhap nam XB: "; cin >> book.namXB;
    cout << "Nhap don gia: "; cin >> book.donGia;
    cout << "Nhap so luong: "; cin >> book.soLuong;
    cout << "Nhap thue VAT: "; cin >> book.thueVAT;
    book.thanhTien = 0; // chưa tính thì khởi tạo là 0
    book.thucTien = 0;
    return book;
}

// Hàm nhập n cuốn sách
void NhapBooks(Book b[], int n){
    for (int i = 0; i < n; i++){
        cout << "Nhap book thu " << i + 1 << ":\n";
        Book book = NhapBook();
        b[i] = book;
        cout << "----------------------------\n";
    }
}

// Hàm in tiêu đề, phục vụ in danh sách dạng bảng
void InTieuDe(){
    cout << setw(20) << "Ma Book";
    cout << setw(20) << "Ten Book";
    cout << setw(20) << "Tac gia";
    cout << setw(20) << "Nha XB";
    cout << setw(20) << "Nam XB";
    cout << setw(20) << "Don gia";
    cout << setw(20) << "So luong";
    cout << setw(20) << "Thanh tien";
    cout << setw(20) << "Thue VAT";
    cout << setw(20) <<"Thuc tien" << "\n";
}

// hàm xuất thông tin 1 cuốn sách
void XuatBook(Book b){
    cout.setf(ios::fixed);
    cout << setw(20) << b.maBook;
    cout << setw(20) << b.tenBook;
    cout << setw(20) << b.tacGia;
    cout << setw(20) << b.nhaXB;
    cout << setw(20) << b.namXB;
    cout << setw(20) << b.donGia;
    cout << setw(20) << b.soLuong;
    cout << setprecision(2) << setw(20) << b.thanhTien;
    cout << setprecision(2) << setw(20) << b.thueVAT;
    cout << setprecision(2) << setw(20) << b.thucTien << "\n";
}

// Hàm xuất thông tin n cuốn sách
void XuatBooks(Book b[], int n){
    // gọi hàm in tiêu đề trước
    InTieuDe();
    // lặp để in ra thông tin từng cuốn
    for(int  i = 0; i < n; i++){
        XuatBook(b[i]);
    }
}

// hàm tính thành tiền cho n cuốn sách
void TinhThanhTien(Book b[], int n){
    for(int i = 0; i < n; i++){
        b[i].thanhTien = b[i].donGia * b[i].soLuong;
    }
}

// hàm tính thực tiền cho n cuốn sách
void TinhThucTien(Book b[], int n){
    for(int i = 0; i < n; i++){
        b[i].thucTien = b[i].thanhTien * (1 + b[i].thueVAT); // 100% số tiền + VAT * số tiền
    }
}

// Hàm sắp xếp giảm dần theo năm XB
void SapXep(Book b[], int n){
    for (int i = 0; i < n; i++){
        for(int j = i+1; j < n; j++){
            // Nếu cuốn trước có năm xuất bản nhỏ hơn cuốn sau thì hoán vị.
            // vì j = i + 1 nên j luôn ở sau i
            if (b[i].namXB < b[j].namXB){
                Book temp = b[i];
                b[i] = b[j];
                b[j] = temp;
            }
        }
    }
}

// Hàm tìm và in thông tin sách có thực tiền lớn nhất.
void MaxSach(Book b[], int n){
    // khởi tạo cuốn đầu tiên là cuốn lớn nhất
    int maxTT = b[0].thucTien;
    int maxIndex = 0; // lưu chỉ số sách lớn nhất hiện tại
    for (int i = 1; i < n; i++){
        if (b[i].thucTien > maxTT){
            maxTT = b[i].thucTien;
            maxIndex = i;
        }
    }
    // in thông tin sách lớn nhất
    cout << "Sach co thuc tien lon nhat la:\n";
    InTieuDe(); // in tiêu đề
    XuatBook(b[maxIndex]); // in thông tin sách
}


// Hàm đếm số lượng cuốn sách, tính tổng số lượng
void TongSoCuonSach(Book b[], int n){
    int tong = 0;
    for(int i = 0; i < n; i++){
        tong += b[i].soLuong;
    }
    cout << "Tong so cuon sach la: " << tong << "\n";
}


// Hàm lọc theo thuế VAT, lặp và tìm cách sách có VAT lớn hơn thì in ra
void LocTheoVAT(Book b[], int n){
    float value;
    cout << "Nhap gia VAT toi thieu: ";
    cin >> value;
    int count = 0;
    for (int i = 0; i < n; i++){
        if (b[i].thueVAT > value){
            if (count == 0){
                // Nếu lần đầu tìm thấy thì in tiêu đề
                InTieuDe();
            }
            XuatBook(b[i]);
            count++;
        }
    }
    // Nếu tìm ko được cuốn nào thì báo ko có
    if (count == 0){
        cout << "Khong tim thay ket qua!\n";
    }
}

// Hàm ghi các cuốn sách ra file
void toFile(Book b[], int n){
    FILE *fptr; // con trỏ file
    fptr = fopen(DATA_PATH,"w"); // mở file
    if(fptr == NULL) {
      printf("Loi mo file!");   
      exit(EXIT_FAILURE);             // thoát chương trình nếu có lỗi mở file
   }
    fprintf(fptr,"%d\n", n); // dòng đầu tiên ghi số cuốn sách
    for (int i = 0; i < n; i++){
        // một cuốn sách ăn sẽ ghi 8 dòng, không ghi thành tiền & thực tiền vào file
        fprintf(fptr, "%s\n%s\n%s\n%s\n%d\n%f\n%d\n%f\n", b[i].maBook, b[i].tenBook, b[i].tacGia, b[i].nhaXB, b[i].namXB, b[i].donGia, b[i].soLuong, b[i].thueVAT);
    }
    printf("Ghi %d cuon sach thanh cong tai %s!\n", n, DATA_PATH);
    fclose(fptr); // đóng file
}

// Hàm đọc các cuốn sách từ file
// n là tham chiếu, vì ta cần thay đổi giá trị của n ở hàm main tại hàm này.
void fromFile(Book b[], int &n){
    FILE *fptr;
    fptr = fopen(DATA_PATH,"r");
    if(fptr == NULL) {
      printf("Loi mo file!\n");   
      exit(EXIT_FAILURE);             // thoát chương trình nếu có lỗi mở file
   }
   char tmp[50];
   fgets(tmp, 50, fptr); // đọc 1 dòng
   n = atoi(tmp); // chuyển chuỗi về số, dòng đầu tiên là số lượng cuốn sách.
   // Kiểm tra số món ăn trong file ko đc vượt qua MAX_SIZE, cũng ko được âm
   if (n < 0 || n > MAX_SIZE){
       printf("So luong cuon sach khong hop le!");
       exit(EXIT_FAILURE);
   }
   for (int i = 0; i < n; i++){
        // đọc 8 dòng để lấy thông tin 1 cuốn sách
        fgets(b[i].maBook, 50, fptr);
        b[i].maBook[strcspn(b[i].maBook, "\n")] = 0; // xóa \n ở cuối
        fgets(b[i].tenBook, 50, fptr);
        b[i].tenBook[strcspn(b[i].tenBook, "\n")] = 0;
        fgets(b[i].tacGia, 50, fptr);
        b[i].tacGia[strcspn(b[i].tacGia, "\n")] = 0;
        fgets(b[i].nhaXB, 50, fptr);
        b[i].nhaXB[strcspn(b[i].nhaXB, "\n")] = 0;
        fgets(tmp, 50, fptr);
        b[i].namXB = atoi(tmp);
        fgets(tmp, 50, fptr);
        b[i].donGia = atof(tmp);
        fgets(tmp, 50, fptr);
        b[i].soLuong = atoi(tmp);
        fgets(tmp, 50, fptr);
        b[i].thueVAT = atof(tmp);
        b[i].thanhTien = b[i].donGia * b[i].soLuong;
        b[i].thucTien = (1 + b[i].thueVAT) * b[i].thanhTien;
   }
   printf("Doc %d cuon sach tu %s thanh cong!\n", n, DATA_PATH);
    fclose(fptr);
}

// Hàm in menu 
void InMenu(){
    cout <<"=================== MENU ======================\n";
    cout << "1. Nhap sach tu ban phim\n";
    cout << "2. Hien thi thong tin cac cuon sach\n";
    cout << "3. Tinh cot thanh tien\n";
    cout << "4. Tinh cot thuc tien\n";
    cout << "5. Sap xep giam dan theo nam xb\n";
    cout << "6. Thong tin sach co thuc tien lon nhat\n";
    cout << "7. In thong tin tong so cac cuon sach\n";
    cout << "8. Loc danh sach theo thue VAT\n";
    cout << "9. Luu ra tep\n";
    cout << "10. Doc tu tep\n";
    cout << "0. Thoat\nLua chon cua ban: ";
}

int main(){
    int n = 0, luaChon;
    Book books[MAX_SIZE];
    while (1){
        InMenu();
        cin >> luaChon;
        switch (luaChon)
        {
        case 1:
            cout << "Nhap so luong book: ";
            cin >> n;
            if (n <= 0 || n > MAX_SIZE){
                cout << "Vui long nhap n trong pham vi 1-100!\n";
                continue;
            }
            NhapBooks(books, n);
            break;
        case 2:
            XuatBooks(books, n);
            break;
        case 3:
            if (n == 0){
                cout << "Vui long nhap du lieu truoc!";
                continue;
            }
            TinhThanhTien(books, n);
            break;
        case 4:
            if (n == 0){
                cout << "Vui long nhap du lieu truoc!";
                continue;
            }
            if (books[0].thanhTien == 0){
                cout << "Vui long tinh thanh tien truoc!";
                continue;
            }
            TinhThucTien(books, n);
            break;
        case 5:
            if (n == 0){
                cout << "Vui long nhap du lieu truoc!";
                continue;
            }
            SapXep(books, n);
            break;
        case 6:
            if (n == 0){
                cout << "Vui long nhap du lieu truoc!";
                continue;
            }
            MaxSach(books, n);
            break;
        case 7:
            if (n == 0){
                cout << "Vui long nhap du lieu truoc!";
                continue;
            }
            TongSoCuonSach(books, n);
            break;
        case 8:
            if (n == 0){
                cout << "Vui long nhap du lieu truoc!";
                continue;
            }
            LocTheoVAT(books, n);
            break;
        case 9:
            if (n == 0){
                cout << "Vui long nhap du lieu truoc!";
                continue;
            }
            toFile(books, n);
            break;
        case 10:
            fromFile(books, n);
            XuatBooks(books, n);
            break;
        case 0:
            cout << "Tam biet!\n";
            exit(0);
        default:
            cout << "Vui long lua chon cac chuc nang tu 0 - 10!\n";
            continue;
        }
    }
}

Kết quả chạy chương trình:

=================== MENU ======================
1. Nhap sach tu ban phim
2. Hien thi thong tin cac cuon sach
3. Tinh cot thanh tien
4. Tinh cot thuc tien
5. Sap xep giam dan theo nam xb
6. Thong tin sach co thuc tien lon nhat
7. In thong tin tong so cac cuon sach
8. Loc danh sach theo thue VAT
9. Luu ra tep
10. Doc tu tep
0. Thoat
Lua chon cua ban: 1
Nhap so luong book: 2
Nhap book thu 1:
Nhap ma book: LT01
Nhap ten book: Lap Trinh Khong Kho 
Nhap ten TG: Nguyen Van Hieu 
Nhap nha XB: Tu do 
Nhap nam XB: 2020
Nhap don gia: 100000
Nhap so luong: 100
Nhap thue VAT: 0.1
----------------------------
Nhap book thu 2:
Nhap ma book: LC01
Nhap ten book: Luyen Code 
Nhap ten TG: Nguyen Van Hieu 
Nhap nha XB: Tu do 
Nhap nam XB: 2021
Nhap don gia: 200000
Nhap so luong: 50
Nhap thue VAT: 0.2
----------------------------
=================== MENU ======================
1. Nhap sach tu ban phim
2. Hien thi thong tin cac cuon sach
3. Tinh cot thanh tien
4. Tinh cot thuc tien
5. Sap xep giam dan theo nam xb
6. Thong tin sach co thuc tien lon nhat
7. In thong tin tong so cac cuon sach
8. Loc danh sach theo thue VAT
9. Luu ra tep
10. Doc tu tep
0. Thoat
Lua chon cua ban: 2
             Ma Book            Ten Book             Tac gia              Nha XB              Nam XB             Don gia            So luong          Thanh tien            Thue VAT           Thuc tien
                LT01 Lap Trinh Khong Kho     Nguyen Van Hieu               Tu do                2020              100000                 100                   0                 0.1                   0
                LC01          Luyen Code     Nguyen Van Hieu               Tu do                2021              200000                  50                   0                 0.2                   0
=================== MENU ======================
1. Nhap sach tu ban phim
2. Hien thi thong tin cac cuon sach
3. Tinh cot thanh tien
4. Tinh cot thuc tien
5. Sap xep giam dan theo nam xb
6. Thong tin sach co thuc tien lon nhat
7. In thong tin tong so cac cuon sach
8. Loc danh sach theo thue VAT
9. Luu ra tep
10. Doc tu tep
0. Thoat
Lua chon cua ban: 3
=================== MENU ======================
1. Nhap sach tu ban phim
2. Hien thi thong tin cac cuon sach
3. Tinh cot thanh tien
4. Tinh cot thuc tien
5. Sap xep giam dan theo nam xb
6. Thong tin sach co thuc tien lon nhat
7. In thong tin tong so cac cuon sach
8. Loc danh sach theo thue VAT
9. Luu ra tep
10. Doc tu tep
0. Thoat
Lua chon cua ban: 2
             Ma Book            Ten Book             Tac gia              Nha XB              Nam XB             Don gia            So luong          Thanh tien            Thue VAT           Thuc tien
                LT01 Lap Trinh Khong Kho     Nguyen Van Hieu               Tu do                2020              100000                 100               1e+07                 0.1                   0
                LC01          Luyen Code     Nguyen Van Hieu               Tu do                2021              200000                  50               1e+07                 0.2                   0
=================== MENU ======================
1. Nhap sach tu ban phim
2. Hien thi thong tin cac cuon sach
3. Tinh cot thanh tien
4. Tinh cot thuc tien
5. Sap xep giam dan theo nam xb
6. Thong tin sach co thuc tien lon nhat
7. In thong tin tong so cac cuon sach
8. Loc danh sach theo thue VAT
9. Luu ra tep
10. Doc tu tep
0. Thoat
Lua chon cua ban: 4
=================== MENU ======================
1. Nhap sach tu ban phim
2. Hien thi thong tin cac cuon sach
3. Tinh cot thanh tien
4. Tinh cot thuc tien
5. Sap xep giam dan theo nam xb
6. Thong tin sach co thuc tien lon nhat
7. In thong tin tong so cac cuon sach
8. Loc danh sach theo thue VAT
9. Luu ra tep
10. Doc tu tep
0. Thoat
Lua chon cua ban: 2
             Ma Book            Ten Book             Tac gia              Nha XB              Nam XB             Don gia            So luong          Thanh tien            Thue VAT           Thuc tien
                LT01 Lap Trinh Khong Kho     Nguyen Van Hieu               Tu do                2020              100000                 100               1e+07                 0.1             1.1e+07
                LC01          Luyen Code     Nguyen Van Hieu               Tu do                2021              200000                  50               1e+07                 0.2             1.2e+07
=================== MENU ======================
1. Nhap sach tu ban phim
2. Hien thi thong tin cac cuon sach
3. Tinh cot thanh tien
4. Tinh cot thuc tien
5. Sap xep giam dan theo nam xb
6. Thong tin sach co thuc tien lon nhat
7. In thong tin tong so cac cuon sach
8. Loc danh sach theo thue VAT
9. Luu ra tep
10. Doc tu tep
0. Thoat
Lua chon cua ban: 5
=================== MENU ======================
1. Nhap sach tu ban phim
2. Hien thi thong tin cac cuon sach
3. Tinh cot thanh tien
4. Tinh cot thuc tien
5. Sap xep giam dan theo nam xb
6. Thong tin sach co thuc tien lon nhat
7. In thong tin tong so cac cuon sach
8. Loc danh sach theo thue VAT
9. Luu ra tep
10. Doc tu tep
0. Thoat
Lua chon cua ban: 2
             Ma Book            Ten Book             Tac gia              Nha XB              Nam XB             Don gia            So luong          Thanh tien            Thue VAT           Thuc tien
                LC01          Luyen Code     Nguyen Van Hieu               Tu do                2021              200000                  50               1e+07                 0.2             1.2e+07
                LT01 Lap Trinh Khong Kho     Nguyen Van Hieu               Tu do                2020              100000                 100               1e+07                 0.1             1.1e+07
=================== MENU ======================
1. Nhap sach tu ban phim
2. Hien thi thong tin cac cuon sach
3. Tinh cot thanh tien
4. Tinh cot thuc tien
5. Sap xep giam dan theo nam xb
6. Thong tin sach co thuc tien lon nhat
7. In thong tin tong so cac cuon sach
8. Loc danh sach theo thue VAT
9. Luu ra tep
10. Doc tu tep
0. Thoat
Lua chon cua ban: 6
Sach co thuc tien lon nhat la:
             Ma Book            Ten Book             Tac gia              Nha XB              Nam XB             Don gia            So luong          Thanh tien            Thue VAT           Thuc tien
                LC01          Luyen Code     Nguyen Van Hieu               Tu do                2021              200000                  50               1e+07                 0.2             1.2e+07
=================== MENU ======================
1. Nhap sach tu ban phim
2. Hien thi thong tin cac cuon sach
3. Tinh cot thanh tien
4. Tinh cot thuc tien
5. Sap xep giam dan theo nam xb
6. Thong tin sach co thuc tien lon nhat
7. In thong tin tong so cac cuon sach
8. Loc danh sach theo thue VAT
9. Luu ra tep
10. Doc tu tep
0. Thoat
Lua chon cua ban: 7
Tong so cuon sach la: 150
=================== MENU ======================
1. Nhap sach tu ban phim
2. Hien thi thong tin cac cuon sach
3. Tinh cot thanh tien
4. Tinh cot thuc tien
5. Sap xep giam dan theo nam xb
6. Thong tin sach co thuc tien lon nhat
7. In thong tin tong so cac cuon sach
8. Loc danh sach theo thue VAT
9. Luu ra tep
10. Doc tu tep
0. Thoat
Lua chon cua ban: 8
Nhap gia VAT toi thieu: 0.15
             Ma Book            Ten Book             Tac gia              Nha XB              Nam XB             Don gia            So luong          Thanh tien            Thue VAT           Thuc tien
                LC01          Luyen Code     Nguyen Van Hieu               Tu do                2021              200000                  50               1e+07                 0.2             1.2e+07
=================== MENU ======================
1. Nhap sach tu ban phim
2. Hien thi thong tin cac cuon sach
3. Tinh cot thanh tien
4. Tinh cot thuc tien
5. Sap xep giam dan theo nam xb
6. Thong tin sach co thuc tien lon nhat
7. In thong tin tong so cac cuon sach
8. Loc danh sach theo thue VAT
9. Luu ra tep
10. Doc tu tep
0. Thoat
Lua chon cua ban: 9
Ghi 2 cuon sach thanh cong tai books.dat!
=================== MENU ======================
1. Nhap sach tu ban phim
2. Hien thi thong tin cac cuon sach
3. Tinh cot thanh tien
4. Tinh cot thuc tien
5. Sap xep giam dan theo nam xb
6. Thong tin sach co thuc tien lon nhat
7. In thong tin tong so cac cuon sach
8. Loc danh sach theo thue VAT
9. Luu ra tep
10. Doc tu tep
0. Thoat
Lua chon cua ban: 10
Doc 2 cuon sach tu books.dat thanh cong!
             Ma Book            Ten Book             Tac gia              Nha XB              Nam XB             Don gia            So luong          Thanh tien            Thue VAT           Thuc tien
                LC01          Luyen Code     Nguyen Van Hieu               Tu do                2021              200000                  50               1e+07                 0.2             1.2e+07
                LT01 Lap Trinh Khong Kho     Nguyen Van Hieu               Tu do                2020              100000                 100               1e+07                 0.1             1.1e+07
=================== MENU ======================
1. Nhap sach tu ban phim
2. Hien thi thong tin cac cuon sach
3. Tinh cot thanh tien
4. Tinh cot thuc tien
5. Sap xep giam dan theo nam xb
6. Thong tin sach co thuc tien lon nhat
7. In thong tin tong so cac cuon sach
8. Loc danh sach theo thue VAT
9. Luu ra tep
10. Doc tu tep
0. Thoat
Lua chon cua ban: 0
Tam biet!

Qua một số bài tập struct trong C/C+ trên đây, LTKK hi vọng các bạn có thể bổ sung thêm kiến thức về kiểu cấu trúc trong C/C++. Chúc các bạn học tốt!

Similar Posts

Subscribe
Notify of
guest
4 Bình luận
Inline Feedbacks
View all comments