From e6db1d1ef824a884e8ec6fbb636dcc3b181d0d66 Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 29 Dec 2020 22:52:02 +0800 Subject: ... --- cpp-practicum/main.cpp | 281 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 281 insertions(+) create mode 100644 cpp-practicum/main.cpp (limited to 'cpp-practicum/main.cpp') diff --git a/cpp-practicum/main.cpp b/cpp-practicum/main.cpp new file mode 100644 index 0000000..0f90b74 --- /dev/null +++ b/cpp-practicum/main.cpp @@ -0,0 +1,281 @@ +#include "Base.hpp" +#include "StringUtil.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include + +inline std::u16string_view ToUtf16View(const std::wstring &str) { + return std::u16string_view(reinterpret_cast(str.c_str()), + str.size()); +} + +inline std::wstring_view ToWStringView(std::u16string_view str) { + return std::wstring_view(reinterpret_cast(str.data()), + str.size()); +} + +class SerializationException : public std::runtime_error { +public: + using runtime_error::runtime_error; +}; + +std::vector SplitByVerticalLine(std::string_view str, + int field_count) { + std::vector fields; + gsl::index current_position = 0; + + for (int i = 0; i < field_count - 1; i++) { + auto pos = str.find('|', current_position); + if (pos == std::string::npos) { + throw SerializationException("Failed to find next splitter('|')."); + } + fields.push_back(str.substr(current_position, pos - current_position)); + current_position = pos + 1; + } + fields.push_back(str.substr(current_position)); + + return fields; +} + +class Book final { +public: + Book() = default; + + Book(std::u16string isbn, std::u16string title, std::u16string type, + std::u16string author, std::u16string press, int stock_count) + : isbn_(std::move(isbn)), title_(std::move(title)), + type_(std::move(type)), author_(std::move(author)), + press_(std::move(press)), stock_count_(stock_count) {} + + CRU_DEFAULT_COPY(Book) + CRU_DEFAULT_MOVE(Book) + + ~Book() = default; + +public: + std::u16string GetIsbn() const { return isbn_; } + void SetIsbn(std::u16string isbn) { isbn_ = std::move(isbn); } + + std::u16string GetTitle() const { return title_; } + void SetTitle(std::u16string title) { title_ = std::move(title); } + + std::u16string GetType() const { return type_; } + void SetType(std::u16string type) { type_ = std::move(type); } + + std::u16string GetAuthor() const { return author_; } + void SetAuthor(std::u16string author) { author_ = std::move(author); } + + std::u16string GetPress() const { return press_; } + void SetPress(std::u16string press) { press_ = std::move(press); } + + int GetStockCount() const { return stock_count_; } + void SetStockCount(int stock_count) { stock_count_ = stock_count; } + +private: + std::u16string isbn_; + std::u16string title_; + std::u16string type_; + std::u16string author_; + std::u16string press_; + int stock_count_; +}; + +std::istream &operator>>(std::istream &left, Book &right) { + std::string line; + std::getline(left, line); + + std::vector fields = SplitByVerticalLine(line, 6); + + right.SetIsbn(cru::ToUtf16(fields[0])); + right.SetTitle(cru::ToUtf16(fields[1])); + right.SetType(cru::ToUtf16(fields[2])); + right.SetAuthor(cru::ToUtf16(fields[3])); + right.SetPress(cru::ToUtf16(fields[4])); + right.SetStockCount(std::stoi(std::string(fields[5]))); + + return left; +} + +std::ostream &operator<<(std::ostream &left, const Book &right) { + left << cru::ToUtf8(right.GetIsbn()) << '|' << cru::ToUtf8(right.GetTitle()) + << '|' << cru::ToUtf8(right.GetType()) << '|' + << cru::ToUtf8(right.GetAuthor()) << '|' << cru::ToUtf8(right.GetPress()) + << '|' << right.GetStockCount(); + return left; +} + +void PrettyPrint(std::wostream &stream, const Book &book) { + stream << L"ISBN: " << ToWStringView(book.GetIsbn()) << L"\n"; + stream << L"标题: " << ToWStringView(book.GetTitle()) << L"\n"; + stream << L"类型: " << ToWStringView(book.GetType()) << L"\n"; + stream << L"作者: " << ToWStringView(book.GetAuthor()) << L"\n"; + stream << L"出版社: " << ToWStringView(book.GetPress()) << L"\n"; + stream << L"库存: " << book.GetStockCount() << L"\n"; +} + +class Vendor final { +public: + Vendor() = default; + Vendor(int id, std::u16string name, std::u16string type, + std::u16string address, std::u16string phone) + : id_(id), name_(std::move(name)), type_(std::move(type)), + address_(std::move(address)), phone_(std::move(phone)) {} + + CRU_DEFAULT_COPY(Vendor) + CRU_DEFAULT_MOVE(Vendor) + + ~Vendor() = default; + +public: + int GetId() const { return id_; } + void SetId(int id) { id_ = id; } + + std::u16string GetName() const { return name_; } + void SetName(std::u16string name) { name_ = std::move(name); } + + std::u16string GetType() const { return type_; } + void SetType(std::u16string type) { type_ = std::move(type); } + + std::u16string GetAddress() const { return address_; } + void SetAddress(std::u16string address) { address_ = std::move(address); } + + std::u16string GetPhone() const { return phone_; } + void SetPhone(std::u16string phone) { phone_ = std::move(phone); } + +private: + int id_; + std::u16string name_; + std::u16string type_; + std::u16string address_; + std::u16string phone_; +}; + +std::istream &operator>>(std::istream &left, Vendor &right) { + std::string line; + std::getline(left, line); + + std::vector fields = SplitByVerticalLine(line, 5); + + right.SetId(std::stoi(std::string(fields[0]))); + right.SetName(cru::ToUtf16(fields[1])); + right.SetType(cru::ToUtf16(fields[2])); + right.SetAddress(cru::ToUtf16(fields[3])); + right.SetPhone(cru::ToUtf16(fields[4])); + + return left; +} + +std::ostream &operator<<(std::ostream &left, const Vendor &right) { + left << right.GetId() << '|' << cru::ToUtf8(right.GetName()) << '|' + << cru::ToUtf8(right.GetType()) << '|' << cru::ToUtf8(right.GetAddress()) + << '|' << cru::ToUtf8(right.GetPhone()); + return left; +} + +class Record final { +public: + Record(); + + CRU_DEFAULT_COPY(Record); + CRU_DEFAULT_MOVE(Record); + + ~Record() = default; + +public: + void WriteTo(std::ostream &stream); + void ReadFrom(std::istream &stream); + + const std::vector &GetBooks() const { return books_; } + const std::vector &GetVendors() const { return vendors_; } + + // TODO: Implementation + std::optional FindBookByIsbn(std::u16string_view isbn); + + // TODO: Implementation + void RemoveBookByIsbn(std::u16string_view isbn); + +private: + std::vector books_; + std::vector vendors_; +}; + +void Record::WriteTo(std::ostream &stream) { + stream << books_.size() << ' ' << vendors_.size() << '\n'; + for (const auto &book : books_) { + stream << book << '\n'; + } + for (const auto &vendor : vendors_) { + stream << vendor << '\n'; + } +} + +void Record::ReadFrom(std::istream &stream) { + books_.clear(); + vendors_.clear(); + int book_count, vendor_count; + stream >> book_count >> vendor_count; + stream >> std::ws; + for (int i = 0; i < book_count; i++) { + Book book; + stream >> book; + books_.push_back(std::move(book)); + } + for (int i = 0; i < vendor_count; i++) { + Vendor vendor; + stream >> vendor; + vendors_.push_back(std::move(vendor)); + } +} + +int main() { + Record record; + + while (true) { + std::wcout << L"1. 查询 2. 添加 0. 退出\n"; + int choice = 0; + std::wcin >> choice; + if (choice == 1) { + std::wcout + << L"1. 图书 2. 供应商\n输入数字选择操作,其他任意字符将退出程序。\n"; + choice = 0; + std::wcin >> choice; + if (choice == 1) { + std::wcout << L"请输入图书编号:\n"; + std::wstring isbn; + std::wcin >> isbn; + auto find_result = record.FindBookByIsbn(ToUtf16View(isbn)); + if (find_result) { + PrettyPrint(std::wcout, *find_result); + std::wcout << L"0. 返回主菜单 1. 修改 2. 删除\n"; + choice = 0; + std::wcin >> choice; + if (choice == 1) { + // TODO: + } else if (choice == 2) { + record.RemoveBookByIsbn(ToUtf16View(isbn)); + std::wcout << L"删除成功。\n"; + } + } else { + std::wcout << L"该书不存在。\n"; + } + } else if (choice == 2) { + + } else { + return 0; + } + + } else if (choice == 2) { + + } else { + return 0; + } + } + + return 0; +} -- cgit v1.2.3