避免使用cin >>。

This commit is contained in:
unlockable
2023-06-24 01:22:11 +08:00
parent ab35d0d2ce
commit 69bf58e48f
5 changed files with 179 additions and 95 deletions

View File

@@ -229,11 +229,12 @@ void ListDisplay::reapplyFilter() {
} }
void ListDisplay::promptForRecordID() { void ListDisplay::promptForRecordID() {
unsigned targetID; int targetID;
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Record ID to search for: " << resetOutputColor; << "Record ID to search for: " << resetOutputColor << std::flush;
std::cin >> targetID; // std::cin >> targetID;
std::cin.ignore(); targetID = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
try { try {
this->allRecordsPtrList this->allRecordsPtrList
.search([&](BaseRecord *const &rescordPtr) -> bool { .search([&](BaseRecord *const &rescordPtr) -> bool {
@@ -261,36 +262,48 @@ void ListDisplay::promptForFromDate() {
<< std::endl; << std::endl;
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Year: " << resetOutputColor << std::flush; << "Year: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
curDate->tm_year = curDate->tm_year =
(tempInput == 0 ? curDate->tm_year : tempInput - 1900); (tempInput == 0 ? curDate->tm_year : tempInput - 1900);
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Month: " << resetOutputColor << std::flush; << "Month: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("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) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Day: " << resetOutputColor << std::flush; << "Day: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("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 { else {
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Year: " << resetOutputColor << std::flush; << "Year: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("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) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Month: " << resetOutputColor << std::flush; << "Month: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("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) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Day: " << resetOutputColor << std::flush; << "Day: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("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);
@@ -310,36 +323,48 @@ void ListDisplay::promptForToDate() {
<< std::endl; << std::endl;
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Year: " << resetOutputColor << std::flush; << "Year: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
curDate->tm_year = curDate->tm_year =
(tempInput == 0 ? curDate->tm_year : tempInput - 1900); (tempInput == 0 ? curDate->tm_year : tempInput - 1900);
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Month: " << resetOutputColor << std::flush; << "Month: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("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) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Day: " << resetOutputColor << std::flush; << "Day: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("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 { else {
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Year: " << resetOutputColor << std::flush; << "Year: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("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) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Month: " << resetOutputColor << std::flush; << "Month: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("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) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Day: " << resetOutputColor << std::flush; << "Day: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("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_hour = 0;
@@ -364,8 +389,10 @@ void ListDisplay::promptForSearchStuID() {
<< "Enter 0 to retain original value." << std::endl; << "Enter 0 to retain original value." << std::endl;
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Student ID: " << resetOutputColor << std::flush; << "Student ID: " << resetOutputColor << std::flush;
std::cin >> tempStuID; // std::cin >> tempStuID;
std::cin.ignore(); // std::cin.ignore();
tempStuID = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
this->searchForStu.setNumber(tempStuID == 0 ? this->searchForStu.getNumber() this->searchForStu.setNumber(tempStuID == 0 ? this->searchForStu.getNumber()
: tempStuID); : tempStuID);
this->reapplyFilter(); this->reapplyFilter();
@@ -385,8 +412,9 @@ void ListDisplay::promptForSearchStuName() {
<< "Enter 0 to retain original value." << std::endl; << "Enter 0 to retain original value." << std::endl;
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Student Name: " << resetOutputColor << std::flush; << "Student Name: " << resetOutputColor << std::flush;
std::cin >> tempStuName; // std::cin >> tempStuName;
std::cin.ignore(); // std::cin.ignore();
std::getline(std::cin, tempStuName);
this->searchForStu.setName(tempStuName == "0" ? this->searchForStu.getName() this->searchForStu.setName(tempStuName == "0" ? this->searchForStu.getName()
: tempStuName); : tempStuName);
this->reapplyFilter(); this->reapplyFilter();
@@ -402,8 +430,9 @@ void ListDisplay::promptForCourseName() {
<< std::endl; << std::endl;
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Course name: " << resetOutputColor << std::flush; << "Course name: " << resetOutputColor << std::flush;
std::cin >> tempCourseName; // std::cin >> tempCourseName;
std::cin.ignore(); // std::cin.ignore();
std::getline(std::cin, tempCourseName);
this->searchForCourseName = this->searchForCourseName =
(tempCourseName == "0" ? this->searchForCourseName : tempCourseName); (tempCourseName == "0" ? this->searchForCourseName : tempCourseName);
this->reapplyFilter(); this->reapplyFilter();
@@ -420,8 +449,9 @@ void ListDisplay::promptForRecordType() {
std::cout << "Choices are: 1. (L)ate, 2. (A)bsent, 3. (P)ersonal\n"; std::cout << "Choices are: 1. (L)ate, 2. (A)bsent, 3. (P)ersonal\n";
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Search for record type: " << resetOutputColor << std::flush; << "Search for record type: " << resetOutputColor << std::flush;
std::cin >> tempIn; // std::cin >> tempIn;
std::cin.ignore(); // std::cin.ignore();
std::getline(std::cin, tempIn);
if (tempIn == "0") { if (tempIn == "0") {
return; return;
} }
@@ -453,8 +483,10 @@ void ListDisplay::promptRecordNumPerPage() {
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "New record number per page: " << resetOutputColor << "New record number per page: " << resetOutputColor
<< std::flush; << std::flush;
std::cin >> tempPerPageNum; // std::cin >> tempPerPageNum;
std::cin.ignore(); // std::cin.ignore();
tempPerPageNum = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
if (tempPerPageNum <= 0) { if (tempPerPageNum <= 0) {
std::cout << setoutputcolor(ConsoleColorTool::red) std::cout << setoutputcolor(ConsoleColorTool::red)
<< "Not a valid number! Record number per page not changed." << "Not a valid number! Record number per page not changed."

View File

@@ -3,14 +3,14 @@
#include <iomanip> #include <iomanip>
#include <iostream> #include <iostream>
unsigned BaseRecord::nextRecordID = 1; int BaseRecord::nextRecordID = 1;
BaseRecord::BaseRecord(const time_t _date, const std::string _courseName, BaseRecord::BaseRecord(const time_t _date, const std::string _courseName,
const int _studentNumber, const std::string _studentName) const int _studentNumber, const std::string _studentName)
: recordID(nextRecordID++), date(_date), courseName(_courseName), : recordID(nextRecordID++), date(_date), courseName(_courseName),
student(_studentNumber, _studentName){}; student(_studentNumber, _studentName){};
BaseRecord::BaseRecord(const unsigned _recordID, const time_t _date, BaseRecord::BaseRecord(const int _recordID, const time_t _date,
const std::string _courseName, const int _studentNumber, const std::string _courseName, const int _studentNumber,
const std::string _studentName) const std::string _studentName)
: recordID(_recordID), date(_date), courseName(_courseName), : recordID(_recordID), date(_date), courseName(_courseName),
@@ -19,7 +19,7 @@ BaseRecord::BaseRecord(const unsigned _recordID, const time_t _date,
BaseRecord::~BaseRecord() { BaseRecord::~BaseRecord() {
} }
const unsigned BaseRecord::getRecordID() const { const int BaseRecord::getRecordID() const {
return this->recordID; return this->recordID;
} }
@@ -57,36 +57,48 @@ void BaseRecord::promptForNewDate(bool showOriginal) {
<< std::endl; << std::endl;
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Year: " << resetOutputColor << std::flush; << "Year: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
newDate.tm_year = newDate.tm_year =
(tempInput == 0 ? curDate->tm_year : tempInput - 1900); (tempInput == 0 ? curDate->tm_year : tempInput - 1900);
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Month: " << resetOutputColor << std::flush; << "Month: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("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) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Day: " << resetOutputColor << std::flush; << "Day: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("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 { else {
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Year: " << resetOutputColor << std::flush; << "Year: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
newDate.tm_year = tempInput - 1900; newDate.tm_year = tempInput - 1900;
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Month: " << resetOutputColor << std::flush; << "Month: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
newDate.tm_mon = tempInput - 1; newDate.tm_mon = tempInput - 1;
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Day: " << resetOutputColor << std::flush; << "Day: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
newDate.tm_mday = tempInput; newDate.tm_mday = tempInput;
} }
this->date = mktime(&newDate); this->date = mktime(&newDate);
@@ -110,8 +122,9 @@ void BaseRecord::promptForNewCourseName(bool showOriginal) {
} }
else { else {
std::cout << "Course name: " << std::flush; std::cout << "Course name: " << std::flush;
std::cin >> this->courseName; // std::cin >> this->courseName;
std::cin.ignore(); // std::cin.ignore();
std::getline(std::cin, courseName);
} }
} }
@@ -131,9 +144,10 @@ void BaseRecord::promptForNewStudentInfo(bool showOriginal) {
<< "Enter 0 to retain original value." << std::endl; << "Enter 0 to retain original value." << std::endl;
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Student ID: " << resetOutputColor << std::flush; << "Student ID: " << resetOutputColor << std::flush;
std::cin >> tempStuID; // std::cin >> tempStuID;
std::cin.ignore(); // std::cin.ignore();
std::cin.ignore(); tempStuID = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
this->student.setNumber(tempStuID == 0 ? this->student.getNumber() this->student.setNumber(tempStuID == 0 ? this->student.getNumber()
: tempStuID); : tempStuID);
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
@@ -145,14 +159,17 @@ void BaseRecord::promptForNewStudentInfo(bool showOriginal) {
else { else {
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Student ID: " << resetOutputColor << std::flush; << "Student ID: " << resetOutputColor << std::flush;
std::cin >> tempStuID; // std::cin >> tempStuID;
std::cin.ignore(); // std::cin.ignore();
tempStuID = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
this->student.setNumber(tempStuID); this->student.setNumber(tempStuID);
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Student Name: " << resetOutputColor << std::flush; << "Student Name: " << resetOutputColor << std::flush;
std::cin >> tempStuName; // std::cin >> tempStuName;
// std::cin.ignore();
std::getline(std::cin, tempStuName);
this->student.setName(tempStuName); this->student.setName(tempStuName);
std::cin.ignore();
} }
} }
@@ -204,7 +221,7 @@ LateRecord::LateRecord(const time_t _date, const std::string _courseName,
const int _studentNumber, const std::string _studentName) const int _studentNumber, const std::string _studentName)
: BaseRecord(_date, _courseName, _studentNumber, _studentName){}; : BaseRecord(_date, _courseName, _studentNumber, _studentName){};
LateRecord::LateRecord(const unsigned _recordID, const time_t _date, LateRecord::LateRecord(const int _recordID, const time_t _date,
const std::string _courseName, const int _studentNumber, const std::string _courseName, const int _studentNumber,
const std::string _studentName) const std::string _studentName)
: BaseRecord(_recordID, _date, _courseName, _studentNumber, _studentName){}; : BaseRecord(_recordID, _date, _courseName, _studentNumber, _studentName){};
@@ -233,7 +250,7 @@ AbsentRecord::AbsentRecord(const time_t _date, const std::string _courseName,
const std::string _studentName) const std::string _studentName)
: BaseRecord(_date, _courseName, _studentNumber, _studentName){}; : BaseRecord(_date, _courseName, _studentNumber, _studentName){};
AbsentRecord::AbsentRecord(const unsigned _recordID, const time_t _date, AbsentRecord::AbsentRecord(const int _recordID, const time_t _date,
const std::string _courseName, const std::string _courseName,
const int _studentNumber, const int _studentNumber,
const std::string _studentName) const std::string _studentName)
@@ -264,7 +281,7 @@ PersonalLeaveRecord::PersonalLeaveRecord(const time_t _date,
const std::string _studentName) const std::string _studentName)
: BaseRecord(_date, _courseName, _studentNumber, _studentName){}; : BaseRecord(_date, _courseName, _studentNumber, _studentName){};
PersonalLeaveRecord::PersonalLeaveRecord(const unsigned _recordID, PersonalLeaveRecord::PersonalLeaveRecord(const int _recordID,
const time_t _date, const time_t _date,
const std::string _courseName, const std::string _courseName,
const int _studentNumber, const int _studentNumber,

View File

@@ -6,7 +6,7 @@
/* /*
The file should be in this stucture: The file should be in this stucture:
int totalRecordNum int totalRecordNum
unsigned nextRecordID int nextRecordID
SaveRecord SaveRecord
courseName char[] courseName char[]
@@ -28,7 +28,7 @@ enum RecordType { Late, Absent, PersonalLeave, Any };
}; };
struct SaveRecord { struct SaveRecord {
unsigned recordID; int recordID;
time_t date; time_t date;
unsigned long courseNameLength; unsigned long courseNameLength;
int studentNumber; int studentNumber;
@@ -39,23 +39,23 @@ struct SaveRecord {
class BaseRecord { class BaseRecord {
protected: protected:
unsigned recordID; int recordID;
Date date; Date date;
std::string courseName; std::string courseName;
Student student; Student student;
public: public:
static unsigned nextRecordID; static int nextRecordID;
BaseRecord() = delete; BaseRecord() = delete;
// Create new record // Create new record
BaseRecord(const time_t _date, const std::string _courseName, BaseRecord(const time_t _date, const std::string _courseName,
const int _studentNumber, const std::string _studentName); const int _studentNumber, const std::string _studentName);
// Read from file // Read from file
BaseRecord(const unsigned _recordID, const time_t _date, BaseRecord(const int _recordID, const time_t _date,
const std::string _courseName, const int _studentNumber, const std::string _courseName, const int _studentNumber,
const std::string _studentName); const std::string _studentName);
virtual ~BaseRecord(); virtual ~BaseRecord();
const unsigned getRecordID() const; const int getRecordID() const;
const Date &getDate() const; const Date &getDate() const;
const std::string getCourseName() const; const std::string getCourseName() const;
const int getStudentNumber() const; const int getStudentNumber() const;
@@ -77,7 +77,7 @@ class LateRecord : public BaseRecord {
public: public:
LateRecord(const time_t _date, const std::string _courseName, LateRecord(const time_t _date, const std::string _courseName,
const int _studentNumber, const std::string _studentName); const int _studentNumber, const std::string _studentName);
LateRecord(const unsigned _recordID, const time_t _date, LateRecord(const int _recordID, const time_t _date,
const std::string _courseName, const int _studentNumber, const std::string _courseName, const int _studentNumber,
const std::string _studentName); const std::string _studentName);
virtual ~LateRecord(); virtual ~LateRecord();
@@ -90,7 +90,7 @@ class AbsentRecord : public BaseRecord {
public: public:
AbsentRecord(const time_t _date, const std::string _courseName, AbsentRecord(const time_t _date, const std::string _courseName,
const int _studentNumber, const std::string _studentName); const int _studentNumber, const std::string _studentName);
AbsentRecord(const unsigned _recordID, const time_t _date, AbsentRecord(const int _recordID, const time_t _date,
const std::string _courseName, const int _studentNumber, const std::string _courseName, const int _studentNumber,
const std::string _studentName); const std::string _studentName);
virtual ~AbsentRecord(); virtual ~AbsentRecord();
@@ -104,7 +104,7 @@ public:
PersonalLeaveRecord(const time_t _date, const std::string _courseName, PersonalLeaveRecord(const time_t _date, const std::string _courseName,
const int _studentNumber, const int _studentNumber,
const std::string _studentName); const std::string _studentName);
PersonalLeaveRecord(const unsigned _recordID, const time_t _date, PersonalLeaveRecord(const int _recordID, const time_t _date,
const std::string _courseName, const int _studentNumber, const std::string _courseName, const int _studentNumber,
const std::string _studentName); const std::string _studentName);
virtual ~PersonalLeaveRecord(); virtual ~PersonalLeaveRecord();

View File

@@ -148,7 +148,7 @@ void StudentInfoManager::readFile() {
} }
fileObj.read((char *)&totalNum, sizeof(int)); fileObj.read((char *)&totalNum, sizeof(int));
fileObj.read((char *)&BaseRecord::nextRecordID, sizeof(unsigned)); fileObj.read((char *)&BaseRecord::nextRecordID, sizeof(int));
while (totalNum > 0 && !fileObj.rdstate()) { while (totalNum > 0 && !fileObj.rdstate()) {
fileObj.read((char *)&tempReadRecord, sizeof(SaveRecord)); fileObj.read((char *)&tempReadRecord, sizeof(SaveRecord));
@@ -206,7 +206,7 @@ void StudentInfoManager::saveFile() {
} }
fileObj.write((char *)&totalNum, sizeof(int)); fileObj.write((char *)&totalNum, sizeof(int));
fileObj.write((char *)&BaseRecord::nextRecordID, sizeof(unsigned)); fileObj.write((char *)&BaseRecord::nextRecordID, sizeof(int));
Iterator<BaseRecord *> iter = this->recordPtrList.iterate(); Iterator<BaseRecord *> iter = this->recordPtrList.iterate();
while (iter) { while (iter) {
@@ -223,7 +223,6 @@ void StudentInfoManager::saveFile() {
} }
void StudentInfoManager::closeFile() { void StudentInfoManager::closeFile() {
if (this->hasChangePendingSave) { if (this->hasChangePendingSave) {
char commandLetter; char commandLetter;
int backSpaceCount = 0; int backSpaceCount = 0;
@@ -366,18 +365,24 @@ bool StudentInfoManager::cmdNew() {
tm newDate; tm newDate;
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Year: " << resetOutputColor << std::flush; << "Year: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
newDate.tm_year = tempInput - 1900; newDate.tm_year = tempInput - 1900;
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Month: " << resetOutputColor << std::flush; << "Month: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
newDate.tm_mon = tempInput - 1; newDate.tm_mon = tempInput - 1;
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Day: " << resetOutputColor << std::flush; << "Day: " << resetOutputColor << std::flush;
std::cin >> tempInput; // std::cin >> tempInput;
std::cin.ignore(); // std::cin.ignore();
tempInput = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
newDate.tm_mday = tempInput; newDate.tm_mday = tempInput;
newDate.tm_hour = 0; newDate.tm_hour = 0;
newDate.tm_min = 0; newDate.tm_min = 0;
@@ -392,8 +397,10 @@ bool StudentInfoManager::cmdNew() {
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Student ID: " << resetOutputColor << std::flush; << "Student ID: " << resetOutputColor << std::flush;
std::cin >> studentID; // std::cin >> studentID;
std::cin.ignore(); // std::cin.ignore();
studentID = safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Student Name: " << resetOutputColor << std::flush; << "Student Name: " << resetOutputColor << std::flush;
@@ -424,8 +431,11 @@ bool StudentInfoManager::cmdRemove() {
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Record ID of which to be removed: " << resetOutputColor << "Record ID of which to be removed: " << resetOutputColor
<< std::endl; << std::endl;
std::cin >> recordIDToRemove; // std::cin >> recordIDToRemove;
std::cin.ignore(); // std::cin.ignore();
recordIDToRemove =
safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
try { try {
this->recordPtrList.remove([=](BaseRecord *const &recordPtr) -> bool { this->recordPtrList.remove([=](BaseRecord *const &recordPtr) -> bool {
return recordPtr->getRecordID() == recordIDToRemove; return recordPtr->getRecordID() == recordIDToRemove;
@@ -447,8 +457,11 @@ bool StudentInfoManager::cmdModify() {
std::cout << setoutputcolor(ConsoleColorTool::blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Record ID of which to be modified: " << resetOutputColor << "Record ID of which to be modified: " << resetOutputColor
<< std::endl; << std::endl;
std::cin >> recordIDToModify; // std::cin >> recordIDToModify;
std::cin.ignore(); // std::cin.ignore();
recordIDToModify =
safeInputNum<int>("Please input a positive integer.\n",
[](const int &num) { return num > 0; });
try { try {
toChangeRecordPtr = this->recordPtrList.search( toChangeRecordPtr = this->recordPtrList.search(
[=](BaseRecord *const &recordPtr) -> bool { [=](BaseRecord *const &recordPtr) -> bool {
@@ -897,12 +910,10 @@ void StudentInfoManager::mainloop() {
} }
else if (cmd == infoManagerCommand::home::closeFile) { else if (cmd == infoManagerCommand::home::closeFile) {
this->closeFile(); this->closeFile();
this->hasChangePendingSave = false;
this->promptForFileName(); this->promptForFileName();
} }
else if (cmd == infoManagerCommand::home::quit) { else if (cmd == infoManagerCommand::home::quit) {
this->closeFile(); this->closeFile();
this->hasChangePendingSave = false;
run = false; run = false;
} }
} }

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include <iostream> #include <iostream>
#include <sstream>
// Reference: https://cplusplus.com/forum/unices/36461/ // Reference: https://cplusplus.com/forum/unices/36461/
// Reference: https://isocpp.org/wiki/faq/input-output#turn-off-tty-echo // Reference: https://isocpp.org/wiki/faq/input-output#turn-off-tty-echo
@@ -53,14 +54,17 @@ const std::string setMiddle(const std::string str, const int targetLength,
void clearScreen(); void clearScreen();
// Disables user input to be echoed back to the console. Operating system specific. // Disables user input to be echoed back to the console. Operating system
// specific.
void disableEchoBack(); void disableEchoBack();
// Enables user input to be echoed back to the console. Operating system specific // Enables user input to be echoed back to the console. Operating system
// specific
void enableEchoBack(); void enableEchoBack();
// Go back num characters, print num spaces, and then go back num spaces, so // Go back num characters, print num spaces, and then go back num spaces, so
// that the previous num characters are removed. Operating system specific (maybe?) // that the previous num characters are removed. Operating system specific
// (maybe?)
void backSpace(int num); void backSpace(int num);
struct termSize { struct termSize {
@@ -71,4 +75,24 @@ struct termSize {
// Return the size of the command line terminal // Return the size of the command line terminal
const termSize getConsoleSize(); const termSize getConsoleSize();
void waitForAnyInput(); void waitForAnyInput();
template <typename T>
T safeInputNum(
std::string notValidNumberWarning = "Not a valid number, try again.\n",
std::function<bool(const T &)> const &isValidNumberFunc =
[](const T &) -> bool { return true; }) {
std::string temp;
T result;
while (true) {
std::getline(std::cin, temp);
std::stringstream tempStrStream(temp);
if (tempStrStream >> result && isValidNumberFunc(result)) {
break;
}
std::cout << notValidNumberWarning << std::flush;
}
return result;
}