Các file Input
Figure 1.1 Yêu cầu cơ bản của chương trình
• Xây dựng chương trình để quản lí thư viện với các file In put là:
– BookMarc.csv: Mục đích của file này để quản lí thông tin biên mục sách của mỗi quyển sách sẽ bao gồm các thông tin cơ bản của một cuốn sách như: Book_id (mã sách), Title (tiêu đề) , Author (tác giả), Publisher (nhà xuất bản), Year (năm phát hành), ISBN.
– Book.csv: Mục đích của file này là quản lí thông tin lưu trữ của mỗi quyển sách với các thuộc tính là: Book_id (mã sách), Store_id (số nhập kho có dạng là NgayThangNamSTT Ví dụ: 190220221), Quantity (số lượng hiện có), Status (tình trạng: availbable, borrowed).
– Ngoài ra em bổ sung thêm một file bổ trợ là adminaccount.csv bao gồm các tài khoản của admin Các tài khoản này sẽ được truy cập với vai trò Admin của chương trình, được truy cập những chức năng như: thêm, sửa, xóa các thông tin của thư viện File bao gồm 2 thông tin chính là: AdminName và Password.
Chức năng chính
Chức năng cho Admin
Khi muốn sử dụng chương trìnhh với vai trò Admin cần đăng nhập bằng tài khoản đã có sẵn Các tài khoản này được lưu trữ trong file adminaccount.csv.
Giao diện menu của Admin sẽ thể hiện các chức năng cơ bản chính:
• Manage Bookmarc Information: Quản lí thông tin các biên mục sách bao gồm các chức năng nhỏ sau:
– Display BookMarc: Hiển thị tất cả thông tin biên mục của tất cả cuốn sách hiện có trong thư viện.
– Add a new BookMarc from console: Thêm mới một biên mục sách từ bàn phím.
– Edit BookMarc: Chỉnh sửa thông tin một BookMarc hiện có.
– Delete Bookmarc: Xóa một biên mục sách hiện có.
– Exit: Thoát Admin Menu hiện tại.
• Manage Book Storage Information: Quản lí thông tin lưu trữ tất cả cuốn sách hiện có tại thư viện Bao gồm các chức năng sau:
– Display Book: Hiển thị tất cả thông tin lưu trữ của tất cả cuốn sách hiện có trong thư viện.
– Add a new Book from console: Thêm mới một thông tin lưu trữ một cuốn sách từ bàn phím.
– Edit Book: Chỉnh sửa thông tin lưu trữ của một quyển sách hiện có.
– Delete Book: Xóa một thông tin lưu trữ của một hiện có.
– Exit: Thoát Admin Menu hiện tại.
Figure 1.4 Manage Book Storage Information
• Search Book Detail: Tra cứu thông tin về tất cả cuốn sách hiện có tại thư viện.
Thông tin mỗi quyển sách được kết hợp từ 2 file BookMarc.csv và file Book.csv. Book Detail sẽ được hiểu là bao gồm: Book_id, Store_id, Quantity, Status, Title, Author, Publisher, Year, ISBN Bao gồm các chức năng sau:
– Display all book details: Hiển thị thông tin của tất cả quyển sách hiện có
– Find detail of a book by ID: Tìm kiếm thông tin của một quyển sách bằng ID.
Figure 1.5 Search Book Detail Information
Chức năng cho Guest
Đối với khách khi sử dụng sẽ không cần tài khoản đăng nhập như Admin do đó sẽ có hạn chế về một số chức năng Guest khi sử dụng chương trình sẽ được tra cứu thông tin các quyển sách hiện có và không được thêm, sửa, xóa các thông tin của thư viện.
Giao diện của Guest sẽ thể hiện các chức năng chính:
• Display detail of every book in the library: Hiển thị thông tin của tất cả quyển sách hiện có giúp người đọc dễ dàng nắm bắt tình hình mượn trả
• Find detail of a book by Book ID: Người đọc hoàn toàn có thể tìm kiếm thông tin của một quyển sách thông qua ID của quyển sách đó
→Chức năng của khách tuy hạn chế nhưng cũng đáp ứng đủ nhu cầu đối với một người đọc khi sử dụng dịch vụ của thư viện.
Các file trong project
Chương trình được chia thành các file nhỏ Mỗi file sẽ có chức năng riêng
Figure 1.7 Cấu trúc chương trình
• Book.cpp: File này được sử dụng để lưu các thao tác (thêm, sửa, xóa, tìm kiếm) dữ liệu trong file Book.csv.
• BookMarc.cpp: File này được sử dụng để lưu các thao tác (thêm, sửa, xóa, tìm kiếm) với dữ liệu trong file BookMarc.csv.
• safe_stoi.cpp: File này được sử dụng để lưu thao tác chuyển an toàn từ string sang integer Thao tác này được gọi nhiểu lần trong file Book.cpp và BookMarc.cpp nên được tạo một file riêng để thuận tiện trong việc nhắc lại
• main.cpp: File main được sử dụng để thiết kế giao diện đơn giản và chứa thao tác với book detail do book detail được kết hợp giữa Book và BookMarc nên được để ở file main.cpp
• Book.h: File này được sử dụng để chứa cấu trúc dữ liệu của file input Book.csv và gọi các hàm được viết ở file Book.cpp
• BookMarc.h: File này được sử dụng để chứa cấu trúc dữ liệu của file input Book-
Marc.csv và gọi các hàm được viết ở file BookMarc.cpp
• safe_stoi.h: File này được sử dụng để gọi hàm được viết ở file safe_stoi.cpp
MÔ TẢ CẤU TRÚC CHƯƠNG TRÌNH 6
File safe_stoi
Dùng để gọi các hàm được viết trong file safe_stoi.cpp, việc khai báo file này trong các file nguồn khác sẽ tránh việc khai báo hàm này nhiều lần
Khi đọc dữ liệu từ file csv việc sử dụng safe_stoi là một điều vô cùng quan trọng và cần thiết Hàm này sẽ giúp ta chuyển đổi dữ liệu một cách an toàn, giúp tránh các trường hợp ngoại lệ bằng cách trả về 0 giúp đoạn mã có thể hoạt động mà không bị gián đoạn.Ngoài ra việc sử dụng hàm này giúp đơn giản mã nguồn và giúp đoạn mã hoạt động ổn định.
File BookMarc.h
Phần đầu sẽ định nghĩa cấu trúc của dữ liệu trong file BookMarc.csv Cấu trúc dữ liệu này bao gồm các thành phần sau:
• book_id: Là một mã số nguyênintđại diện cho mã số sách
• title: Là một chuỗistringđại diện cho tiêu đề của cuốn sách
• author: Là một chuỗistringđại diện cho tên tác giả của cuốn sách
• publisher: Là một chuỗistringđại diện cho NXB của cuốn sách
• year: Là một số nguyênintđại diện cho năm xuất bản của cuốn sách
• ISBN: Là một chuỗistringđại diện cho mã số quốc tế của cuốn sách
Phần sau sẽ gọi các hàm được viết trong file BookMarc.cpp
File BookMarc.cpp
File này được sử dụng để chứa các hàm thao tác với BookMarc, chứa phần code của chức năng lớn Manage BookMarc Information.
• Hàm này được sử dụng để đọc dữ liệu từ file input BookMarc.csv để phục vụ cho các thao tác khác.
• Cấu trúc của hàm như sau:
– Định nghĩa hàm: hàm này tên là ReadBookMarcFromCSV, hàm này nhận tham chiếu của chuỗi để chiếu đến tên file sẽ đọc dữ Hàm này trả về vector để lưu trữ các đối tượng BookMarc.
– Khai báo biến: Khai báo vector để lưu trữ các đối tượng BookMarc được đọc từ file csv.
– Đọc file CSV: Nếu mở file bị lỗi sẽ trả về BookMarcList.
– Kiểm tra tính duy nhất của Book_id: Sử dụng một tập hợp book_id_set để kiểm tra tính trùng lặp của book_id nếu có sẽ báo lỗi và book_id trùng lặp sẽ được đưa vào
– Đọc từng dòng của file CSV: Sẽ đọc từ dòng đầu tiên của file csv đến dòng cuối cùng sau các đối tượng BookMarc được đọc sẽ được thêm vào BookMar- cList Cuối cùng đóng file và trả về BookMarcList.
• Khi đọc dữ liệu từ file BookMarc, file safe_stoi được sử dụng xuyên suốt để có thể chuyển an toàn dữ liệu từ dạng string sang int.
• Hàm này được sử dụng để in các BookMarc ra màn hình.
• Hàm nhận vào tham chiếu hằng chiếu đến các vector BookMarc và không trả về giá trị nào nên khai báo kiểuvoid.
• Sử dụng vòng lặp for để in ra tất cả các thông tin của BookMarc.
Hàm này được sử dụng để xóa một đối tượng BookMar đã có sẵn Cấu trúc của hàm như sau:
• Hàm mở tệp CSV để đọc và một tệp tạm thời để ghi.
• Duyệt qua từng dòng của tệp gốc, kiểm tra book_id.
• Nếu book_id khớp, dòng đó sẽ bị bỏ qua.
• Các dòng không khớp được ghi vào tệp tạm thời.
• Đóng cả hai tệp sau khi hoàn tất.
• Nếu book_id không được tìm thấy, xóa tệp tạm thời và thông báo Nếu book_id được tìm thấy, xóa tệp gốc và đổi tên tệp tạm thời thành tệp gốc.
Hàm này được sử dụng để kiểm tra tính duy nhất của thuộc tính book_id Cấu trúc hàm như sau:
• Mở tệp: Hàm mở tệp CSV để đọc Nếu không thể mở tệp, hàm in ra thông báo lỗi và trả về true để ngăn việc thêm dữ liệu mới.
• Đọc và phân tích cú pháp: Hàm đọc từng dòng của tệp, phân tích cú pháp để tách các trường và tạo đối tượng BookMarc.
• Kiểm tra trùng lặp: Kiểm tra book_id của đối tượng trong tệp có khớp với book_id của đối tượng mới hay không Nếu có, in ra thông báo và trả về true.
• Đóng Tệp: Đóng tệp sau khi hoàn tất việc đọc.
• Trả về kết quả: Nếu không tìm thấy đối tượng nào trùng lặp, trả về false.
Hàm này được sử dụng để kiểm tra định dạng của các thuộc tính của đối tượng BookMarc Hàm được sử dụng để kiểm tra dữ liệu nhập vào khi người dùng sử dụng tính năng Add a new BookMarc Cụ thể như sau:
• book_id: Phải là số nguyên không âm.
• year: Là số nguyên không âm.
Nếu tất cả các thuộc tính đều hợp lệ, hàm trả về true Nếu có bất kỳ thuộc tính nào không hợp lệ, hàm in ra thông báo lỗi và trả về false.
Hàm AddBookMarcFromConsole cho phép người dùng nhập thông tin sách mới từ bàn phím và lưu thông tin này vào cuối tệp BookMarc.csv Trước khi thêm, hàm kiểm tra tính hợp lệ của dữ liệu và tránh thêm các bản ghi trùng lặp Quá trình nhập dữ liệu được kiểm soát và xử lý để đảm bảo tính chính xác và đáng tin cậy của dữ liệu trong tệp.Cấu trúc hàm như sau:
• Định nghĩa hàm: Hàm AddBookMarcFromConsole nhận vào một tham số file- name, đây là tên của tệp CSV mà thông tin sách mới sẽ được thêm vào.
• Mở tệp để ghi: Mở file csv để ghi nếu không mở được sẽ báo lõip và thoát khỏi hàm.
• Nhập thông tin sách: Người dùng sẽ được yêu cầu nhập các thông tin: book_id, title, author, publisher.
• Kiểm tra và nhập năm: Người dùng được yêu cầu nhập year (năm xuất bản) và hàm sẽ kiểm tra tính hợp lệ của giá trị nhập vào Nếu giá trị không phải là số nguyên không âm lớn hơn năm hiện tại sẽ in ra thông báo lỗi và yêu cầu nhập lại.
• Kiểm tra và nhập ISBN: Người dùng được yêu cầu nhập isbn và sau đó kiểm tra tính hợp lệ của dữ liệu nhập vào bằng cách gọi hàm ValidateInput Nếu dữ liệu nhập không hợp lệ, in ra thông báo lỗi và thoát khỏi hàm.
• Kiểm tra trùng : Kiểm tra xem đối tượng newBook có trùng lặp với bất kỳ đối tượng nào đã có trong tệp CSV hay không, bằng cách gọi hàm CheckDuplicate. Nếu có trùng lặp, in ra thông báo lỗi và thoát khỏi hàm.
• Ghi đối tượng newbook vào tệp: Nếu không có lỗi gì xảy ra và newBook không trùng lặp, ghi thông tin của newBook vào tệp CSV.
• Đóng tệp và lưu kết quả: In ra thông báo khi đã thêm sách mới thành công Đóng tệp sau khi ghi dữ liệu.
Hàm EditBookMarcInCSV được thiết kế để chính sửa thông tin của một cuốn sách trong file BookMarc.csv dựa trên book_id Dưới đây là phân tích chi tiết về cách hoạt động của hàm này:
• Mở file đầu vào và tạo file tạm thời:
– Hàm bắt đầu bằng việc mở file filename để đọc dữ liệu và temp.csv để ghi dữ liệu sau khi chỉnh sửa.
– Nếu không mở được file đầu vào "filename", thông báo lỗi và thoát khỏi hàm.
– Nếu không mở được file tạm thời "temp.csv", đóng file đầu vào và thoát khỏi hàm.
• Đọc từng dòng trong file đầu vào:
– Hàm sử dụng vòng lặp while để đọc từng dòng trong file đầu vào inputFile.
– Mỗi dòng được đọc và xử lý thông qua stringstream để trích xuất từng trường dữ liệu "token".
• Kiểm tra book_id và thực hiện chỉnh sửa:
– Nếu currentBookId (đọc từ trường đầu tiên của dòng) bằng book_id cần chỉnh sửa, hàm tiến hành hiển thị menu để người dùng lựa chọn trường cần cập nhật.
– Dùng switch để xử lý từng lựa chọn:
* Case 1-5: Mỗi case tương ứng với từng trường cần cập nhật (title, author, publisher, year, isbn).
* Đối với mỗi trường, người dùng được yêu cầu nhập giá trị mới.
* Trước khi cập nhật, hàm kiểm tra xem giá trị mới có trùng với giá trị hiện tại không và có hợp lệ hay không (với year và isbn sử dụng hàm ValidateYear và ValidateISBN).
* Sau khi cập nhật giá trị, thông tin mới được ghi vào tempFile.
• Ghi dữ liệu vào file tạm thời:
– Sau khi xử lý xong mỗi dòng, thông tin được ghi vào tempFile với các trường đã được cập nhật (nếu có).
• Kiểm tra và xử lý kết quả:
– Nếu không tìm thấy book_id trong file đầu vào, thông báo lỗi và xóa temp.csv.
– Sau khi ghi hoàn tất, file gốc (filename) được xóa và file tạm thời (temp.csv) được đổi tên thành tên file gốc.
– Nếu có lỗi trong quá trình xóa hoặc đổi tên file, thông báo lỗi tương ứng.
– Nếu quá trình sửa đổi thành công, thông báo "Book with ID has been updated successfully."
File Book.h
Phần đầu sẽ định nghĩa cấu trúc của dữ liệu trong file Book.csv Cấu trúc dữ liệu này bao gồm các thành phần sau:
• book_id: Là một mã số nguyênintđại diện cho mã số sách
• store_id: Là một mã số nguyênintđại diện cho mã số nhập
• quantity: Là một mã số nguyênintđại diện cho số lượng quyển sách hiện có
• status: Là một chuỗi string đại diện cho tình trạng sách hiện tại (available hoặc borrowed)
Phần sau sẽ gọi các hàm được viết trong file Book.cpp
File Book.cpp
File này được sử dụng để chứa các hàm thao tác với BookMarc, chứa phần code của chức năng lớn Manage BookMarc Information.
2.5.1 Hàm ReadBookFromCSV Đoạn mã ReadBookFromCSV có nhiệm vụ đọc dữ liệu từ file Book.csv và chuyển đổi chúng thành các đối tượng Book, sau đó lưu vào một vector Dưới đây là giải thích chi tiết từng phần của mã:
• Mở tệp CSV:Hàm nhận vào tên tệp CSV (filename) và mở tệp để đọc dữ liệu.
• Kiểm tra mở tệp: Nếu tệp không mở được, hiển thị thông báo lỗi và trả về một vector rỗng.
• Đọc từng dòng của tệp: Sử dụng vòng lặp để đọc từng dòng của tệp CSV.
• Phân tích cú pháp và chuyển đổi dữ liệu:
– Sử dụng stringstream để phân tích cú pháp từng dòng.
– Đọc từng giá trị từ dòng, chuyển đổi từ chuỗi thành số nguyên (nếu cần), và gán vào các thuộc tính của đối tượng Book.
• Thêm đối tượng Book vào danh sách: Thêm đối tượng Book đã được điền đầy đủ dữ liệu vào vector bookList.
• Đóng tệp và trả về danh sách sách: Đóng tệp CSV sau khi đọc xong và trả về vector chứa tất cả các đối tượng Book đã được đọc từ tệp CSV.
• Hàm này được sử dụng để in các Book ra màn hình.
• Hàm nhận vào tham chiếu hằng chiếu đến các vector Book và không trả về giá trị nào nên khai báo kiểuvoid.
• Sử dụng vòng lặp for để in ra tất cả các thông tin của Book.
Hàm DeleteBookFromCSV có nhiệm vụ xóa một cuốn sách dựa trên book_id từ một tệp Book.csv Dưới đây là tóm tắt các bước thực hiện của mã:
• Mở tệp và kiểm tra mở tệp: Mở tệp CSV (filename) để đọc nội dung.
• Tạo tệp tạm: NTạo một tệp tạm (temp.csv) để ghi lại các dòng sách sau khi xóa.
• Đọc từng dòng trong tệp gốc: Sử dụng vòng lặp để đọc từng dòng của tệp CSV.
– Sử dụng while (getline(inputFile, line)) để đọc từng dòng của tệp CSV.
– Sử dụng istringstream để phân tích cú pháp dòng và lấy book_id từ dòng hiện tại.
• Kiểm tra và xóa dòng có book_id tương ứng:
– So sánh currentBookId (lấy từ dòng hiện tại) với book_id.
– Đọc từng giá trị từ dòng, chuyển đổi từ chuỗi thành số nguyên (nếu cần), và gán vào các thuộc tính của đối tượng Book.
– Nếu tìm thấy book_id, đánh dấu found = true và bỏ qua dòng đó (không ghi vào tệp tạm).
– Nếu không phải book_id cần xóa, ghi dòng đó vào tempFile.
• Đóng tệp và tệp tạm: Đóng cả tệp gốc và tệp tạm sau khi hoàn thành việc đọc và ghi Nếu thành công, in ra thông báo cho biết book_id đã được xóa thành công.
• Xử lý kết quả và lỗi:
– Nếu không tìm thấy book_id, thông báo không tìm thấy và xóa tệp tạm
– Sử dụng remove để xóa tệp gốc.
– Sử dụng rename để đổi tên tệp tạm thành tên tệp gốc sau khi xóa thành công.
• Thông báo kết quả: Nếu thành công, in ra thông báo cho biết book_id đã được xóa thành công.
Hàm CheckDuplicate có nhiệm vụ kiểm tra xem một cuốn sách mới (newBook) có trùng lặp với các cuốn sách đã có trong tệp CSV hay không Dưới đây là tóm tắt các bước thực hiện của mã:
• Mở tệp và kiểm tra mở tệp:
– Hàm mở tệp CSV (filename) để đọc dữ liệu.
– Nếu không mở được tệp, in ra thông báo lỗi và trả về true, cho rằng có lỗi xảy ra và không thể kiểm tra.
• Đọc từng dòng trong tệp:
– Sử dụng while (getline(file, line)) để đọc từng dòng của tệp.
– Mỗi dòng sẽ được đưa vào stringstream (ss) để phân tích cú pháp và lấy ra book_id và store_id.
• Chuyển đổi dữ liệu từ chuỗi thành số nguyên: Sử dụng getline(ss, temp, ’,’) để lấy từng giá trị trong dòng và chuyển đổi từ chuỗi thành số nguyên bằng hàm safe_stoi.
– So sánh book_id và store_id của từng cuốn sách trong tệp với book_id và store_id của newBook.
– Nếu tìm thấy book_id hoặc store_id của newBook trùng với một trong các cuốn sách đã có trong tệp, in ra thông báo và trả về true, cho biết đã có sự trùng lặp.
• Đóng tệp và trả về kết quả:
– Đóng tệp sau khi hoàn thành việc đọc.
– Nếu không tìm thấy trùng lặp, trả về false, cho biết không có cuốn sách nào trùng lặp với newBook.
Hàm AddBookToCSV có nhiệm vụ cho phép người dùng nhập thông tin của một cuốn sách mới và thêm thông tin này vào tệp CSV sau khi kiểm tra tính hợp lệ và sự trùng lặp của book_id và store_id Dưới đây là phân tích chi tiết từng bước của hàm này:
• Nhập thông tin cuốn sách mới: Người dùng được yêu cầu nhập thông tin của một cuốn sách mới bao gồm book_id, store_id, quantity và status.
• Kiểm tra và nhập book ID:
– Sử dụng cin ằ newBook.book_id để nhập book_id.
– Kiểm tra tớnh hợp lệ của dữ liệu nhập: Nếu cin ằ newBook.book_id thất bại (không phải là số nguyên), in ra thông báo lỗi và quay lại.
• Kiểm tra và nhập store ID:
– Sử dụng cin ằ newBook.store_id để nhập store_id.
– Kiểm tra tớnh hợp lệ của dữ liệu nhập: Nếu cin ằ newBook.store_id thất bại (không phải là số nguyên hoặc nhỏ hơn 0), in ra thông báo lỗi và quay lại.
• Kiểm tra và nhập quantity:
– Sử dụng cin ằ newBook.quantity để nhập quantity.
– Kiểm tra tớnh hợp lệ của dữ liệu nhập: Nếu cin ằ newBook.quantity thất bại(không phải là số nguyên hoặc nhỏ hơn 0), in ra thông báo lỗi và quay lại.
• Kiểm tra và nhập status:
– Sử dụng cin ằ statusInput để nhập status.
– Kiểm tra tớnh hợp lệ của dữ liệu nhập: Nếu cin ằ statusInput thất bại (khụng phải là 0 hoặc 1), in ra thông báo lỗi và quay lại.
– Dựa vào statusInput, thiết lập giá trị cho newBook.status là "available" nếu statusInput là 1 và là "borrowed" nếu là 0.
• Kiểm tra sự trùng lặp:
– Gọi hàm CheckDuplicate(filename, newBook) để kiểm tra xem có sự trùng lặp với book_id hoặc store_id đã có trong tệp không.
– Nếu không có sự trùng lặp (CheckDuplicate trả về false), tiếp tục thực hiện thêm cuốn sách vào tệp CSV.
– Nếu có sự trùng lặp (CheckDuplicate trả về true), in ra thông báo và không thêm cuốn sách vào tệp.
• Thêm cuốn sách mới vào tệp CSV:
– Mở tệp CSV (filename) để ghi vào cuối file (ios::app).
– Nếu không mở được tệp, in ra thông báo lỗi và thoát.
– Sử dụng file ô để ghi thụng tin của newBook vào tệp.
– Đóng tệp sau khi ghi xong và in ra thông báo thành công.
Hàm EditBookInCSV cho phép người dùng chỉnh sửa thông tin của một cuốn sách trong tệp CSV, bao gồm cập nhật store_id, quantity, và status Trước khi cập nhật, hàm kiểm tra tính hợp lệ của dữ liệu nhập và thông báo lỗi nếu cần thiết Sau khi cập nhật, hàm xóa tệp gốc và đổi tên tệp tạm thành tên tệp gốc để lưu thay đổi.
– Kiểm tra xem chuỗi store_id có chứa chỉ chữ số không.
– Duyệt từng ký tự trong store_id, nếu có ký tự không phải là số thì trả về false, ngược lại trả về true.
– Kiểm tra xem chuỗi status có bằng "available" hoặc "borrowed" không.
– Trả về true nếu status là "available" hoặc "borrowed", ngược lại trả về false.
– Mở tệp để đọc (inputFile) và một tệp tạm (tempFile) để ghi.
– Nếu không mở được tệp để đọc, thông báo lỗi và thoát.
– Nếu không mở được tệp tạm để ghi, đóng inputFile và thoát.
• Vòng lặp while để duyệt từng dòng trong tệp gốc (inputFile):
– Dùng getline để lấy từng dòng, sau đó sử dụng stringstream (ss) để phân tách các trường dữ liệu.
– Kiểm tra xem currentBookId (là book_id của cuốn sách hiện tại) có bằng book_id cần sửa không.
– Nếu tìm thấy cuốn sách cần sửa:
* Yêu cầu người dùng chọn trường dữ liệu cần cập nhật (store_id, quantity, status).
* Dựa vào lựa chọn của người dùng, nhập dữ liệu mới và kiểm tra tính hợp lệ.
* Nếu dữ liệu không hợp lệ, in ra thông báo lỗi và ghi lại dòng dữ liệu cũ vào tempFile.
* Nếu hợp lệ, cập nhật dữ liệu mới vào biến tương ứng (store_id, quantity, status).
– Nếu không tìm thấy cuốn sách cần sửa, ghi dòng dữ liệu hiện tại vào tempFile mà không thay đổi.
• Sau khi duyệt hết tệp gốc:
– Nếu không tìm thấy cuốn sách cần sửa, in ra thông báo và xóa temp.csv.
– Xóa tệp gốc (filename) và đổi tên temp.csv thành tên tệp gốc.
– Nếu có lỗi xảy ra trong quá trình xóa hoặc đổi tên tệp, in ra thông báo lỗi.
• Thông báo kết quả:In ra thông báo thành công nếu quá trình sửa đổi thành công.
Hàm FindBookByID được thiết kế để tìm kiếm và hiển thị thông tin của một cuốn sách trong tệp CSV dựa trên book_id Nó sử dụng các thao tác đọc file và xử lý chuỗi để truy cập và so sánh dữ liệu Nếu tìm thấy cuốn sách, nó in ra thông tin chi tiết của cuốn sách và trả về true; nếu không tìm thấy, nó in ra thông báo và trả về false.
• Mở tệp để đọc (ifstream file(filename)): Nếu không mở được tệp (!file.is_open()), in ra thông báo lỗi và trả về false.
• Vòng lặp while (getline(file, line))
– Duyệt từng dòng trong tệp filename.
– Tạo stringstream ss(line) từ dòng hiện tại để phân tách các trường thông tin của sách.
– Tạo một đối tượng Book (book) để lưu trữ thông tin từ dòng hiện tại.
• Phân tách và lưu trữ thông tin từ dòng hiện tại:
– Sử dụng getline(ss, temp, ’,’) để đọc và chuyển đổi các giá trị từ stringstream sang các thành phần của đối tượng book.
– safe_stoi(temp) được sử dụng để chuyển đổi chuỗi temp sang kiểu số nguyên an toàn (int).
– Các trường thông tin của book bao gồm book_id, store_id, quantity, và status.
– So sánh book.book_id với book_id truyền vào.
– Nếu trùng khớp (book.book_id == book_id), in ra thông tin của sách và đóng tệp (file.close()) sau đó trả về true.
• Đóng tệp và thông báo nếu không tìm thấy sách
– Nếu duyệt hết tệp mà không tìm thấy cuốn sách có book_id, đóng tệp (file.close()) và in ra thông báo không tìm thấy sách.
– Trả về false vì không tìm thấy sách có book_id trong tệp.
Hàm FindBookByQuantity được thiết kế để tìm kiếm và hiển thị thông tin của các cuốn sách có quantity nhất định từ tệp Book.csv Nó sử dụng vòng lặp để duyệt qua danh sách các sách và kiểm tra điều kiện tìm kiếm Nếu tìm thấy sách, nó in ra thông tin của sách đó; nếu không tìm thấy, nó in ra thông báo là không có sách nào thỏa mãn điều kiện tìm kiếm Cụ thể như sau:
• Đọc danh sách sách từ file CSV (vector books = ReadBookFromCSV(filename))
Sử dụng hàm ReadBookFromCSV để đọc danh sách sách từ file CSV và lưu vào vector books.
• Khởi tạo biến found để kiểm tra có tìm thấy sách hay không (bool found = false)Biến này được sử dụng để đánh dấu nếu có ít nhất một cuốn sách có quantity như yêu cầu.
• Vòng lặp for (const auto& book : books) Duyệt qua từng phần tử (cuốn sách) trong vector books.
• Kiểm tra quantity của từng cuốn sách (if (book.quantity == quantity))So sánh quantity của cuốn sách hiện tại với quantity được truyền vào hàm.
• In ra thông tin của sách nếu tìm thấy
– Nếu tìm thấy cuốn sách có quantity như yêu cầu, in ra các thông tin của cuốn sách bao gồm book_id, store_id, quantity, và status.
– Đánh dấu found = true để biết là đã tìm thấy ít nhất một cuốn sách.
• Thông báo nếu không tìm thấy sách
– Sau khi kết thúc vòng lặp, kiểm tra biến found.
– Nếu found vẫn là false, in ra thông báo là không tìm thấy cuốn sách nào có quantity như yêu cầu.
Hàm FindBookByStoreID được thiết kế để tìm kiếm và hiển thị thông tin của các cuốn sách có store_id nhất định từ tệp Book.csv Nó sử dụng vòng lặp để duyệt qua danh sách các sách và kiểm tra điều kiện tìm kiếm Nếu tìm thấy sách, nó in ra thông tin của sách đó; nếu không tìm thấy, nó in ra thông báo là không có sách nào thỏa mãn điều kiện tìm kiếm Cụ thể như sau:
• Đọc danh sách sách từ file CSV (vector books = ReadBookFromCSV(filename))
Sử dụng hàm ReadBookFromCSV để đọc danh sách sách từ file CSV và lưu vào vector books.
• Khởi tạo biến found để kiểm tra có tìm thấy sách hay không (bool found = false)Biến này được sử dụng để đánh dấu nếu có ít nhất một cuốn sách có quantity như yêu cầu.
• Vòng lặp for (const auto& book : books) Duyệt qua từng phần tử (cuốn sách) trong vector books.
• Kiểm tra store_id của từng cuốn sách (i f(book.store i d ==store_id)) So sánh store_id của cuốn sách hiện tại với store_id được truyền vào hàm.
• In ra thông tin của sách nếu tìm thấy
– Nếu tìm thấy cuốn sách có store_id như yêu cầu, in ra các thông tin của cuốn sách bao gồm book_id, store_id, quantity, và status.
– Đánh dấu found = true để biết là đã tìm thấy ít nhất một cuốn sách.
• Thông báo nếu không tìm thấy sách
– Sau khi kết thúc vòng lặp, kiểm tra biến found.
– Nếu found vẫn là false, in ra thông báo là không tìm thấy cuốn sách nào có quantity như yêu cầu.
KIỂM THỬ 24
Menu chính
• Khi bắt đầu sử dụng chương trình người dùng có ba lựa chọn là: đăng với vai trò Guest, đăng nhập với vai trò Admin và thoát chương trình
• Khi nhập lựa chọn người dùng chỉ cần nhập số, nếu nhập chữ chương trình sẽ bị lỗi vòng lặp
• Nếu nhập không đúng lựa chọn, chương trình sẽ báo lựa chọn không hợp lệ và nhập lại
Chức năng của Guest
3.2.1 Display detail of every book in the library
∗In ra thông tin chi tiết của tất cả quyển sách hiện có trong thư viện
Figure 3.4 Display detail of every book in the library
3.2.2 Find detail of a book by book_id
∗Tìm thông tin chi tiết của một quyển sách bất kì hiện có trong thư viện
Figure 3.5 Find detail of a book by book_id
∗Trường hợp nhập sai book_id
Figure 3.6 Find detail of a book by book_id
Chức năng của Admin
∗Trường hợp nhập sai tài khoản
(a) User not found (b) Incorrect password
∗Menu của Manage BookMarc Information
∗In ra thông tin của tất cả biên mục sách
3.3.2 Add a new Bookmarc from console
∗Thêm thông tin lưu trữ của một quyển sách
Figure 3.11 Add a new Bookmarc from console
∗Sau khi thêm BookMarc mới sẽ cập nhật luôn vào file BookMarc.csv
Figure 3.12 Add a new Bookmarc from console
∗Trường hợp nhập Book_id đã tồn tại
Figure 3.13 Book_id already exists
∗Trường hợp để trống một trong các thuộc tính
(a) Title is empty (b) Author is empty
∗Nhập năm lớn hơn năm hiện tại
∗Find BookMarc by Book_id
- Tìm biên mục sách của quyển có ID là 23
Figure 3.31 Find BookMarc by Book_id 23
Figure 3.32 Can not find Book_id
- Tìm biên mục sách của quyển có title là The Time Machine
Figure 3.33 Find BookMarc by Book_id 23
Figure 3.34 Can not find the book whose title is gt2
- Tìm biên mục sách của quyển có Author là Willo Cato
Figure 3.35 Find BookMarc by Book_id 23
Figure 3.36 Can not find the book whose author is abc
- Tìm biên mục sách của quyển có Publisher là DHBKHN
Figure 3.37 Find BookMarc by Publisher
Figure 3.38 Can not find the book whose publisher is ABC
- Tìm biên mục sách của quyển có năm xuất bản là 23
Figure 3.39 Find BookMarc by year
Figure 3.40 Can not find the book whose year is 2024
- Tìm biên mục sách của quyển có ISBN là 123
Figure 3.41 Find BookMarc by ISBN
Figure 3.42 Can not find the book whose ÍBN is 098
Figure 3.43 Find BookMarc by ISBN
∗In ra thông tin lưu trữ của tất cả quyển sách
∗Thêm mới một thông tin lưu trữ
Figure 3.45 Add Book To CSV
∗Sau khi thêm sẽ được cập nhật luôn vào file Book.csv
∗Trường hợp nhập số Book_id hoặc Store_id đã tồn tại
Figure 3.47 Book_id or Store_id already exists
∗Trường hợp nhập sai định dạng Book_id
∗Trường hợp nhập sai định dạng Store_id
∗Trường hợp nhập sai định dạng Quantity
∗Trường hợp nhập sai định dạng Status
Figure 3.52 Edit Book In CSV Menu
- Trường hợp nhập sai định dạng của Store_id
- Trường hợp nhập sai định dạng của Quantity
- Trường hợp nhập sai định dạng của Status
∗Xóa thông tin lưu trữ của quyển sách có Book_id 54
Figure 3.62 Delele from Book.csv
∗Trường hợp nhập sai Book_id
Figure 3.63 Can not found Book_id
Figure 3.64 Find by Book_id 5
- Trường hợp Book_id không tồn tại:
Figure 3.65 Can not find Book_id 5
Figure 3.66 Find by Book_id 5
- Trường hợp store_id không tồn tại:
Figure 3.67 Can not find Book_id 5
- Trường hợp Quantity không tồn tại:
Figure 3.69 Can not find Quantity -5
- Trường hợp Status không tồn tại:
Figure 3.71 Can not find Status
CHƯƠNG IV: KIẾN THỨC VẬN DỤNG
Với ngôn ngữ lập trình C++, em đã vận dụng một số lý thuyết vào bài lập trình như sau:
• Cấu trúc điều kiện if – else: Cho phép thực hiện các hành động khác nhau dựa trên điều kiện logic.
• Cấu trúcCấu trúc module hóa:vòng lặp while: Dùng để lặp lại một khối lệnh cho đến khi điều kiện không còn đúng nữa.
• Cấu trúc khai báo và định nghĩa hàm: Giúp tổ chức mã nguồn bằng cách chia các chương trình thành các phần nhỏ, mỗi phần thực hiện một chức năng cụ thể.
• Nguyên tắc đơn trách nhiệm: Mỗi phần của chương trình chỉ nên thực hiện một chức năng duy nhất, từ đó dễ dàng bảo trì và tái sử dụng mã nguồn.
• Cấu trúc module hóa: Chia chương trình thành các module hoặc các chương trình con độc lập, mỗi module có các chức năng riêng biệt, giúp mã nguồn trở nên dễ hiểu hơn, tổ chức rõ ràng và dễ theo dõi.
• Tên hàm và chương trình con rõ ràng: Đặt tên cho các hàm và chương trình con sao cho phản ánh chính xác chức năng của chúng, giúp người đọc dễ dàng hiểu và gợi nhớ chức năng của mỗi phần code.
• Áp dụng comment: Sử dụng comment để giải thích mã nguồn, cung cấp thông tin về cách hoạt động của các đoạn code và mục đích của chúng.
Việc áp dụng các nguyên lý này giúp cho mã nguồn trở nên dễ hiểu, dễ bảo trì, sửa lỗi và tái sử dụng hơn, đồng thời tăng tính rõ ràng và sáng sủa của cấu trúc chương trình.
Các bước trong quá trình gỡ lỗi và kiểm thử có thể được mô tả như sau:
• Xử lý lỗi ngay khi phát hiện.
• Ngừng viết mã cho đến khi sẵn sàng để sửa lỗi.
• Cân nhắc kỹ trước khi viết mã.
• Sử dụng phương pháp chia để trị.
• Hiển thị hoặc xuất thông tin ra.
• Kiểm tra giá trị biên.
• Tạm thời thay đổi mã nguồn.
• Kiểm tra từng bước một.
• Kiểm tra hộp trắng: phân tích logic trong chương trình.
• Kiểm tra hộp đen: phân tích yêu cầu chương trình.