diff --git a/.gitignore b/.gitignore index 2b706bd..397b0c7 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ *.exe **/.vscode/ *.o -*.dat \ No newline at end of file +*.dat +*.ilk +*.pdb \ No newline at end of file diff --git a/大作业/Date.cpp b/大作业/Date.cpp index 13bfa68..ee5a304 100644 --- a/大作业/Date.cpp +++ b/大作业/Date.cpp @@ -39,7 +39,16 @@ std::string Date::toString() const { return "[Any]"; } char buffer[20]; - strftime(buffer, 20, "%F", localtime(&this->time)); + tm curTime; + + #ifdef __APPLE__ + curDate = *(localtime(&this->time)); + #endif + + #if defined _WIN64 || defined _WIN32 + localtime_s(&curTime, &this->time); + #endif + strftime(buffer, 20, "%F", &curTime); return std::string(buffer); } diff --git a/大作业/ListDisplay.cpp b/大作业/ListDisplay.cpp index c77e44b..ffbf5e9 100644 --- a/大作业/ListDisplay.cpp +++ b/大作业/ListDisplay.cpp @@ -260,11 +260,20 @@ void ListDisplay::promptForRecordID() { void ListDisplay::promptForFromDate() { time_t originTime = this->fromDate.getTime(); - tm *curDate = localtime(&originTime); + tm curDate; + + #ifdef __APPLE__ + curDate = *(localtime(&originTime)); + #endif + + #if defined _WIN64 || defined _WIN32 + localtime_s(&curDate, &originTime); + #endif + int tempInput; if (!this->fromDate.isAny()) { char buffer[20]; - strftime(buffer, 20, "%F", curDate); + strftime(buffer, 20, "%F", &curDate); std::cout << setoutputcolor(ConsoleColorTool::green) << "Current date: " << buffer << ". Enter 0 to retain original value." << resetOutputColor @@ -275,22 +284,22 @@ void ListDisplay::promptForFromDate() { // std::cin.ignore(); tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); - curDate->tm_year = - (tempInput == 0 ? curDate->tm_year : tempInput - 1900); + curDate.tm_year = + (tempInput == 0 ? curDate.tm_year : tempInput - 1900); std::cout << setoutputcolor(ConsoleColorTool::blue) << "Month: " << resetOutputColor << std::flush; // std::cin >> tempInput; // std::cin.ignore(); tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); - curDate->tm_mon = (tempInput == 0 ? curDate->tm_mon : tempInput - 1); + curDate.tm_mon = (tempInput == 0 ? curDate.tm_mon : tempInput - 1); std::cout << setoutputcolor(ConsoleColorTool::blue) << "Day: " << resetOutputColor << std::flush; // std::cin >> tempInput; // std::cin.ignore(); tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); - curDate->tm_mday = (tempInput == 0 ? curDate->tm_mday : tempInput); + curDate.tm_mday = (tempInput == 0 ? curDate.tm_mday : tempInput); } else { std::cout << setoutputcolor(ConsoleColorTool::blue) @@ -299,33 +308,43 @@ void ListDisplay::promptForFromDate() { // std::cin.ignore(); tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); - curDate->tm_year = tempInput - 1900; + curDate.tm_year = tempInput - 1900; std::cout << setoutputcolor(ConsoleColorTool::blue) << "Month: " << resetOutputColor << std::flush; // std::cin >> tempInput; // std::cin.ignore(); tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); - curDate->tm_mon = tempInput - 1; + curDate.tm_mon = tempInput - 1; std::cout << setoutputcolor(ConsoleColorTool::blue) << "Day: " << resetOutputColor << std::flush; // std::cin >> tempInput; // std::cin.ignore(); tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); - curDate->tm_mday = tempInput; + curDate.tm_mday = tempInput; } - this->fromDate = mktime(curDate); + this->fromDate = mktime(&curDate); this->reapplyFilter(); } void ListDisplay::promptForToDate() { time_t originTime = this->fromDate.getTime(); - tm *curDate = localtime(&originTime); + + tm curDate; + + #ifdef __APPLE__ + curDate = *(localtime(&originTime)); + #endif + + #if defined _WIN64 || defined _WIN32 + localtime_s(&curDate, &originTime); + #endif + int tempInput; if (!this->toDate.isAny()) { char buffer[20]; - strftime(buffer, 20, "%F", curDate); + strftime(buffer, 20, "%F", &curDate); std::cout << setoutputcolor(ConsoleColorTool::green) << "Current date: " << buffer << ". Enter 0 to retain original value." << resetOutputColor @@ -336,22 +355,22 @@ void ListDisplay::promptForToDate() { // std::cin.ignore(); tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); - curDate->tm_year = - (tempInput == 0 ? curDate->tm_year : tempInput - 1900); + curDate.tm_year = + (tempInput == 0 ? curDate.tm_year : tempInput - 1900); std::cout << setoutputcolor(ConsoleColorTool::blue) << "Month: " << resetOutputColor << std::flush; // std::cin >> tempInput; // std::cin.ignore(); tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); - curDate->tm_mon = (tempInput == 0 ? curDate->tm_mon : tempInput - 1); + curDate.tm_mon = (tempInput == 0 ? curDate.tm_mon : tempInput - 1); std::cout << setoutputcolor(ConsoleColorTool::blue) << "Day: " << resetOutputColor << std::flush; // std::cin >> tempInput; // std::cin.ignore(); tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); - curDate->tm_mday = (tempInput == 0 ? curDate->tm_mday : tempInput); + curDate.tm_mday = (tempInput == 0 ? curDate.tm_mday : tempInput); } else { std::cout << setoutputcolor(ConsoleColorTool::blue) @@ -360,27 +379,27 @@ void ListDisplay::promptForToDate() { // std::cin.ignore(); tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); - curDate->tm_year = tempInput - 1900; + curDate.tm_year = tempInput - 1900; std::cout << setoutputcolor(ConsoleColorTool::blue) << "Month: " << resetOutputColor << std::flush; // std::cin >> tempInput; // std::cin.ignore(); tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); - curDate->tm_mon = tempInput - 1; + curDate.tm_mon = tempInput - 1; std::cout << setoutputcolor(ConsoleColorTool::blue) << "Day: " << resetOutputColor << std::flush; // std::cin >> tempInput; // std::cin.ignore(); tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); - curDate->tm_mday = tempInput; + curDate.tm_mday = tempInput; } - curDate->tm_hour = 0; - curDate->tm_min = 0; - curDate->tm_sec = 0; - curDate->tm_isdst = 0; - this->toDate = mktime(curDate); + curDate.tm_hour = 0; + curDate.tm_min = 0; + curDate.tm_sec = 0; + curDate.tm_isdst = 0; + this->toDate = mktime(&curDate); this->reapplyFilter(); } diff --git a/大作业/ListE.hpp b/大作业/ListE.hpp index d27d959..1d31e9b 100755 --- a/大作业/ListE.hpp +++ b/大作业/ListE.hpp @@ -1,6 +1,7 @@ #pragma once #include "Exceptions.hpp" #include "Node.hpp" +#include template class List { private: diff --git a/大作业/Makefile b/大作业/Makefile index ecc517d..f2bdc9c 100644 --- a/大作业/Makefile +++ b/大作业/Makefile @@ -1,8 +1,11 @@ -generalArguments = -std=c++17 -g +generalArguments = -std=c++20 -g main.out: main.o Tools.o Exceptions.o Record.o Date.o Student.o StudentInfoManager.o ListDisplay.o clang++ $(generalArguments) $^ -o main.out +main.exe: main.o Tools.o Exceptions.o Record.o Date.o Student.o StudentInfoManager.o ListDisplay.o + clang++ $(generalArguments) $^ -o main.exe + main.o: main.cpp ListE.hpp Node.hpp clang++ $(generalArguments) -c main.cpp -o main.o diff --git a/大作业/Record.cpp b/大作业/Record.cpp index fc4f806..fd6018e 100644 --- a/大作业/Record.cpp +++ b/大作业/Record.cpp @@ -45,12 +45,23 @@ const Student &BaseRecord::getStudent() const { void BaseRecord::promptForNewDate(bool showOriginal) { time_t originTime = this->date.getTime(); - tm *curDate = localtime(&originTime); + // tm *curDate = localtime(&originTime); + + tm curDate; + + #ifdef __APPLE__ + curDate = *(localtime(&originTime)); + #endif + + #if defined _WIN64 || defined _WIN32 + localtime_s(&curDate, &originTime); + #endif + tm newDate; int tempInput; if (showOriginal) { char buffer[20]; - strftime(buffer, 20, "%F", curDate); + strftime(buffer, 20, "%F", &curDate); std::cout << setoutputcolor(ConsoleColorTool::green) << "Current date: " << buffer << ". Enter 0 to retain original value." << resetOutputColor @@ -62,21 +73,21 @@ void BaseRecord::promptForNewDate(bool showOriginal) { tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); newDate.tm_year = - (tempInput == 0 ? curDate->tm_year : tempInput - 1900); + (tempInput == 0 ? curDate.tm_year : tempInput - 1900); std::cout << setoutputcolor(ConsoleColorTool::blue) << "Month: " << resetOutputColor << std::flush; // std::cin >> tempInput; // std::cin.ignore(); tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); - newDate.tm_mon = (tempInput == 0 ? curDate->tm_mon : tempInput - 1); + newDate.tm_mon = (tempInput == 0 ? curDate.tm_mon : tempInput - 1); std::cout << setoutputcolor(ConsoleColorTool::blue) << "Day: " << resetOutputColor << std::flush; // std::cin >> tempInput; // std::cin.ignore(); tempInput = safeInputNum("Please input a positive integer.\n", [](const int &num) { return num > 0; }); - newDate.tm_mday = (tempInput == 0 ? curDate->tm_mday : tempInput); + newDate.tm_mday = (tempInput == 0 ? curDate.tm_mday : tempInput); } else { std::cout << setoutputcolor(ConsoleColorTool::blue) @@ -147,7 +158,7 @@ void BaseRecord::promptForNewStudentInfo(bool showOriginal) { // std::cin >> tempStuID; // std::cin.ignore(); tempStuID = safeInputNum("Please input a positive integer.\n", - [](const int &num) { return num > 0; }); + [](const int &num) { return num > 0; }); this->student.setNumber(tempStuID == 0 ? this->student.getNumber() : tempStuID); std::cout << setoutputcolor(ConsoleColorTool::blue) @@ -162,7 +173,7 @@ void BaseRecord::promptForNewStudentInfo(bool showOriginal) { // std::cin >> tempStuID; // std::cin.ignore(); tempStuID = safeInputNum("Please input a positive integer.\n", - [](const int &num) { return num > 0; }); + [](const int &num) { return num > 0; }); this->student.setNumber(tempStuID); std::cout << setoutputcolor(ConsoleColorTool::blue) << "Student Name: " << resetOutputColor << std::flush; diff --git a/大作业/Record.hpp b/大作业/Record.hpp index 9fdbfcc..0bb64ef 100644 --- a/大作业/Record.hpp +++ b/大作业/Record.hpp @@ -23,6 +23,7 @@ const struct { int studentName = 15; int type = 10; } recordDisplayRowSize; + namespace StuRecord { enum RecordType { Late, Absent, PersonalLeave, Any }; }; @@ -30,9 +31,9 @@ enum RecordType { Late, Absent, PersonalLeave, Any }; struct SaveRecord { int recordID; time_t date; - unsigned long courseNameLength; + unsigned long long courseNameLength; int studentNumber; - unsigned long studentNameLength; + unsigned long long studentNameLength; StuRecord::RecordType recordType; }; diff --git a/大作业/StudentInfoManager.cpp b/大作业/StudentInfoManager.cpp index dc5ac28..abe7854 100644 --- a/大作业/StudentInfoManager.cpp +++ b/大作业/StudentInfoManager.cpp @@ -15,10 +15,10 @@ bool StudentInfoManager::promptForFileName() { clearScreen(); std::cout << "\n\n" << setMiddle("Student Info Management", - std::min(getConsoleSize().width, 80)) + std::min(getConsoleSize().width, 120)) << "\n\n\n" << setMiddle("(O)pen file (N)ew file", - std::min(getConsoleSize().width, 80)) + std::min(getConsoleSize().width, 120)) << "\n\n\n" << std::flush; @@ -350,11 +350,21 @@ bool StudentInfoManager::cmdNew() { if (useTodayDate) { time_t curTime; time(&curTime); - tm *curDate = localtime(&curTime); + + tm curDate; + + #ifdef __APPLE__ + curDate = *(localtime(&curTime)); + #endif + + #if defined _WIN64 || defined _WIN32 + localtime_s(&curDate, &curTime); + #endif + tm newDate; - newDate.tm_year = curDate->tm_year; - newDate.tm_mon = curDate->tm_mon; - newDate.tm_mday = curDate->tm_mday; + newDate.tm_year = curDate.tm_year; + newDate.tm_mon = curDate.tm_mon; + newDate.tm_mday = curDate.tm_mday; newDate.tm_hour = 0; newDate.tm_min = 0; newDate.tm_sec = 0; diff --git a/大作业/Tools.cpp b/大作业/Tools.cpp index 29a5f03..e8ba8a4 100644 --- a/大作业/Tools.cpp +++ b/大作业/Tools.cpp @@ -1,11 +1,16 @@ #include "Tools.hpp" #include -#ifdef __API_AVAILABLE_PLATFORM_macosx +#ifdef __APPLE__ #include #include #endif +#if defined _WIN64 || defined _WIN32 +#include +#include +#endif + using namespace ConsoleColorTool; setoutputcolor::setoutputcolor(ConsoleColors _color) @@ -128,7 +133,7 @@ const std::string setMiddle(const std::string str, const int targetLength, return result; } -#ifdef __API_AVAILABLE_PLATFORM_macosx +#ifdef __APPLE__ void clearScreen() { system("clear"); } @@ -165,6 +170,34 @@ const termSize getConsoleSize() { } #endif +#if defined _WIN64 || defined _WIN32 +void clearScreen() { + std::cout << "\x1B[2J\x1B[H" << std::flush; +} + +void disableEchoBack() { + HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); + DWORD mode = 0; + GetConsoleMode(hStdin, &mode); + SetConsoleMode(hStdin, mode & (~ENABLE_ECHO_INPUT) & (~ENABLE_LINE_INPUT) & (~ENABLE_PROCESSED_INPUT)); +} + +void enableEchoBack() { + HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); + DWORD mode = 0; + GetConsoleMode(hStdin, &mode); + SetConsoleMode(hStdin, mode | (ENABLE_ECHO_INPUT) | (ENABLE_LINE_INPUT) | (ENABLE_PROCESSED_INPUT)); +} + +const termSize getConsoleSize() { + CONSOLE_SCREEN_BUFFER_INFO scrInfo; + HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE); + GetConsoleScreenBufferInfo(hStdout, &scrInfo); + return termSize{ .width=scrInfo.dwSize.X, .height=scrInfo.dwSize.Y }; +} + +#endif + void backSpace(int num) { for (int i = 0; i < num; i++) { std::cout << "\033[D"; diff --git a/大作业/Tools.hpp b/大作业/Tools.hpp index 82f43dd..c7ca05a 100644 --- a/大作业/Tools.hpp +++ b/大作业/Tools.hpp @@ -1,11 +1,13 @@ #pragma once #include #include +#include // Reference: https://cplusplus.com/forum/unices/36461/ // Reference: https://isocpp.org/wiki/faq/input-output#turn-off-tty-echo // Reference: // https://forums.codeguru.com/showthread.php?466009-Reading-from-stdin-(without-echo) +// Reference: https://dev.to/tenry/predefined-c-c-macros-43id namespace ConsoleColorTool { enum ConsoleColors { @@ -21,6 +23,11 @@ enum ConsoleColors { }; }; +struct termSize { + int width; + int height; +}; + class setoutputcolor { private: ConsoleColorTool::ConsoleColors color; @@ -67,11 +74,6 @@ void enableEchoBack(); // (maybe?) void backSpace(int num); -struct termSize { - int width; - int height; -}; - // Return the size of the command line terminal const termSize getConsoleSize(); diff --git a/大作业/main.cpp b/大作业/main.cpp index af14938..a536370 100644 --- a/大作业/main.cpp +++ b/大作业/main.cpp @@ -2,6 +2,9 @@ #include "Tools.hpp" int main(int argc, char *argv[]) { + #if defined _WIN64 || defined _WIN32 + system("chcp 65001"); + #endif enableEchoBack(); // Just in case StudentInfoManager *studManager; if (argc > 1) {