更新了数据的存储方式,改为存储指针。

This commit is contained in:
unlockable
2023-06-19 00:50:47 +08:00
parent ae0a2175fd
commit 7ca9f62d4c
13 changed files with 460 additions and 164 deletions

View File

@@ -11,10 +11,12 @@ Date::Date(const tm &_time) : isAny(false) {
} }
void Date::setNewDate(const time_t &newTime) { void Date::setNewDate(const time_t &newTime) {
this->isAny = false;
this->time = newTime; this->time = newTime;
} }
void Date::setNewDate(const tm &newTime) { void Date::setNewDate(const tm &newTime) {
this->isAny = false;
tm temp = newTime; tm temp = newTime;
this->time = mktime(&temp); this->time = mktime(&temp);
} }
@@ -29,6 +31,9 @@ time_t Date::getTime() const {
} }
std::string Date::toString() const { std::string Date::toString() const {
if (this->isAny) {
return "[Any]";
}
char buffer[20]; char buffer[20];
strftime(buffer, 20, "%F", localtime(&this->time)); strftime(buffer, 20, "%F", localtime(&this->time));
return std::string(buffer); return std::string(buffer);

View File

@@ -1,21 +1,75 @@
#include "ListDisplay.hpp" #include "ListDisplay.hpp"
#include "Exceptions.hpp" #include "Exceptions.hpp"
#include "Tools.hpp"
#include <iomanip>
ListDisplay::ListDisplay(const List<BaseRecord> &_allRecords) ListDisplay::ListDisplay(const List<BaseRecord *> &_allRecordsPtrList)
: allRecords(_allRecords), fromDate(), toDate(), recordNumPerPage(20), : allRecordsPtrList(_allRecordsPtrList), fromDate(), toDate(),
currentPage(1), totalPage(allRecords.length() / recordNumPerPage + 1), searchForStu(), recordNumPerPage(20), currentPageIndex(0),
sortOrder(ASCENT), sortByProp(RecordID){}; maxPageIndex(allRecordsPtrList.length() / recordNumPerPage),
sortOrder(ASCENT), sortByProp(RecordID),
tableTitleRow(
"" + setMiddle("Record ID", recordDisplayRowSize.recordID) + "" +
setMiddle("Date", recordDisplayRowSize.date) + "" +
setMiddle("Course Name", recordDisplayRowSize.courseName) + "" +
setMiddle("Stud. ID", recordDisplayRowSize.studentID) + "" +
setMiddle("Stud. name", recordDisplayRowSize.studentName) + "" +
setMiddle("Type", recordDisplayRowSize.type) + "") {
this->filteredRecordsPtrList =
allRecordsPtrList.filtered([](BaseRecord *const &) { return true; });
};
bool ListDisplay::hasNext() { bool ListDisplay::hasNext() {
return currentPage < totalPage; return currentPageIndex < maxPageIndex;
} }
bool ListDisplay::hasPrev() { bool ListDisplay::hasPrev() {
return currentPage > 1; return currentPageIndex > 0;
} }
void ListDisplay::displayNext() { void ListDisplay::displayNext() {
if (!this->hasNext()) { if (!this->hasNext()) {
throw(PageIndexError("No next Page!")); throw(PageIndexError("No next page!"));
}
this->currentPageIndex++;
this->display();
}
void ListDisplay::displayPrev() {
if (!this->hasPrev()) {
throw(PageIndexError("No prev page!"));
}
this->currentPageIndex--;
this->display();
}
void ListDisplay::display() {
bool brightBG = true;
std::cout << setoutputcolor(ConsoleColorTool::blue) << " Search date: from "
<< resetOutputColor << this->fromDate.toString()
<< setoutputcolor(ConsoleColorTool::blue) << " to "
<< resetOutputColor << this->toDate.toString();
std::cout << " ";
std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Search for student: ID: " << resetOutputColor
<< this->searchForStu.getNumberString()
<< setoutputcolor(ConsoleColorTool::blue)
<< " Name: " << resetOutputColor << this->searchForStu.getName()
<< "\n";
// std::cout << setbgcolor(ConsoleColorTool::cyan);
std::cout << this->tableTitleRow << std::endl;
Iterator<BaseRecord *> iter = this->filteredRecordsPtrList.iterate(
this->currentPageIndex * this->recordNumPerPage);
int i = recordNumPerPage;
while (i > 0 && iter) {
if (brightBG) {
std::cout << setbgcolor(ConsoleColorTool::lightGray);
}
iter.next()->display();
if (brightBG) {
std::cout << resetOutputColor;
}
brightBG = !brightBG;
i--;
} }
} }

View File

@@ -15,19 +15,21 @@ enum SortBy {
class ListDisplay { class ListDisplay {
private: private:
const List<BaseRecord> &allRecords; const List<BaseRecord*> &allRecordsPtrList;
List<BaseRecord> filteredRecords; List<BaseRecord*> filteredRecordsPtrList;
Date fromDate; Date fromDate;
Date toDate; Date toDate;
Student searchForStu;
int recordNumPerPage; int recordNumPerPage;
int currentPage; // The current page index, starting from 0
int totalPage; int currentPageIndex;
int maxPageIndex;
bool sortOrder; bool sortOrder;
SortBy sortByProp; SortBy sortByProp;
const std::string tableTitleRow;
public: public:
ListDisplay() = delete; ListDisplay(const List<BaseRecord*> &_allRecordsPtrList);
ListDisplay(const List<BaseRecord> &_allRecords);
bool hasNext(); bool hasNext();
bool hasPrev(); bool hasPrev();
void displayNext(); void displayNext();

View File

@@ -33,9 +33,6 @@ public:
// Swap the element located at index a and b. Throws IndexError if the given // Swap the element located at index a and b. Throws IndexError if the given
// index is beyond length of the list. // index is beyond length of the list.
List<E> &swap(int index_a, int index_b); List<E> &swap(int index_a, int index_b);
// Sort this list.
List<E> &
sort(std::function<bool(const E &, const E &)> const &isCorrectOrderFunc);
E &operator[](const int index); E &operator[](const int index);
const E &operator[](const int index) const; const E &operator[](const int index) const;
List<E> &operator=(const List<E> &otherList); List<E> &operator=(const List<E> &otherList);
@@ -51,10 +48,15 @@ public:
// Only retain item that matches the isTargetFunc // Only retain item that matches the isTargetFunc
List<E> &filter(std::function<bool(const E &)> const &isTargetFunc); List<E> &filter(std::function<bool(const E &)> const &isTargetFunc);
// Returns a new filtered list. // Returns a new filtered list.
List<E> filtered(std::function<bool(const E &)> const &isTargetFunc); List<E> filtered(std::function<bool(const E &)> const &isTargetFunc) const;
// Sort this list.
List<E> &
sort(std::function<bool(const E &, const E &)> const &isCorrectOrderFunc);
// Returns a sorted NEW list. // Returns a sorted NEW list.
const List<E> sorted(std::function<bool(const E &, const E &)> const const List<E> sorted(std::function<bool(const E &, const E &)> const
&isCorrectOrderFunc) const; &isCorrectOrderFunc) const;
Iterator<E> &&iterate();
Iterator<E> &&iterate(int index);
}; };
template <class E> int List<E>::getIndexInRange(int index) const { template <class E> int List<E>::getIndexInRange(int index) const {
@@ -182,6 +184,9 @@ template <class E> E List<E>::pop(int index) {
} }
template <class E> List<E> &List<E>::clear() { template <class E> List<E> &List<E>::clear() {
if (this->_length == 0) {
return *this;
}
this->head->destruct(); this->head->destruct();
this->head = NULL; this->head = NULL;
this->_length = 0; this->_length = 0;
@@ -266,12 +271,13 @@ template <class E> List<E> &List<E>::operator=(const List<E> &otherList) {
if (otherList.length() > 0) { if (otherList.length() > 0) {
this->head = new Node<E>(otherList[0]); this->head = new Node<E>(otherList[0]);
this->_length = 1; this->_length = 1;
Node<E> *nextPtr = otherList->head->getNextPtr(); Node<E> *nextPtr = otherList.head->getNextPtr();
while (nextPtr != NULL) { while (nextPtr != NULL) {
this->append((*nextPtr).getContent()); this->append((*nextPtr).getContent());
nextPtr = (*nextPtr).getNextPtr(); nextPtr = (*nextPtr).getNextPtr();
} }
} }
return *this;
} }
template <class E> int List<E>::length() const { template <class E> int List<E>::length() const {
@@ -342,7 +348,7 @@ List<E> &List<E>::filter(std::function<bool(const E &)> const &isTargetFunc) {
} }
Node<E> *current = this->head; Node<E> *current = this->head;
while(current->getNextPtr() != NULL) { while (current->getNextPtr() != NULL) {
if (!isTargetFunc(current->getNextPtr()->getContent())) { if (!isTargetFunc(current->getNextPtr()->getContent())) {
Node<E> *newNext = current->getNextPtr()->getNextPtr(); Node<E> *newNext = current->getNextPtr()->getNextPtr();
delete current->getNextPtr(); delete current->getNextPtr();
@@ -354,7 +360,8 @@ List<E> &List<E>::filter(std::function<bool(const E &)> const &isTargetFunc) {
return *this; return *this;
} }
template <class E> List<E> List<E>::filtered(std::function<bool(const E&)> const &isTargetFunc) { template <class E>
List<E> List<E>::filtered(std::function<bool(const E &)> const &isTargetFunc) const {
return List<E>(*this).filter(isTargetFunc); return List<E>(*this).filter(isTargetFunc);
} }
@@ -362,4 +369,18 @@ template <class E>
const List<E> List<E>::sorted( const List<E> List<E>::sorted(
std::function<bool(const E &, const E &)> const &isCorrectOrderFunc) const { std::function<bool(const E &, const E &)> const &isCorrectOrderFunc) const {
return List<E>(*this).sort(isCorrectOrderFunc); return List<E>(*this).sort(isCorrectOrderFunc);
}
template <class E>
Iterator<E> &&List<E>::iterate() {
return std::move(Iterator<E>(this->head));
}
template <class E>
Iterator<E> &&List<E>::iterate(int index) {
index = this->getIndexInRange(index);
if (index == 0) {
return std::move(Iterator<E>(this->head));
}
return std::move(Iterator<E>(&this->head->getByIndex(index)));
} }

View File

@@ -1,6 +1,6 @@
generalArguments = -std=c++11 generalArguments = -std=c++20
main.out: main.o Tools.o Exceptions.o Record.o Date.o main.out: main.o Tools.o Exceptions.o Record.o Date.o Student.o ListDisplay.o
clang++ $(generalArguments) -g $^ -o main.out clang++ $(generalArguments) -g $^ -o main.out
main.o: main.cpp main.o: main.cpp
@@ -9,11 +9,17 @@ main.o: main.cpp
Exceptions.o: Exceptions.cpp Exceptions.o: Exceptions.cpp
clang++ $(generalArguments) -g -c Exceptions.cpp -o Exceptions.o clang++ $(generalArguments) -g -c Exceptions.cpp -o Exceptions.o
Record.o: Record.cpp Record.o: Record.cpp
clang++ $(generalArguments) -g -c Record.cpp -o Record.o clang++ $(generalArguments) -g -c Record.cpp -o Record.o
Date.o: Date.cpp Date.o: Date.cpp
clang++ $(generalArguments) -g -c Date.cpp -o Date.o clang++ $(generalArguments) -g -c Date.cpp -o Date.o
Tools.o: Tools.cpp Tools.o: Tools.cpp
clang++ $(generalArguments) -g -c Tools.cpp -o Tools.o clang++ $(generalArguments) -g -c Tools.cpp -o Tools.o
ListDisplay.o: ListDisplay.cpp
clang++ $(generalArguments) -g -c ListDisplay.cpp -o ListDisplay.o
Student.o: Student.cpp
clang++ $(generalArguments) -g -c Student.cpp -o Student.o

View File

@@ -27,6 +27,18 @@ public:
void destruct(); void destruct();
}; };
template <class E> class Iterator {
private:
Node<E> *current;
public:
Iterator(Node<E> *pos);
bool hasNext();
// Return the same as hasNext();
operator bool();
E &next();
};
template <class E> Node<E>::Node() : content(0), nextNode(NULL){}; template <class E> Node<E>::Node() : content(0), nextNode(NULL){};
template <class E> template <class E>
@@ -72,4 +84,23 @@ template <class E> void Node<E>::destruct() {
this->nextNode->destruct(); this->nextNode->destruct();
} }
delete this; delete this;
}
template <class E> Iterator<E>::Iterator(Node<E> *start) : current(start){};
template <class E> bool Iterator<E>::hasNext() {
return this->current != NULL;
}
template <class E> Iterator<E>::operator bool() {
return this->hasNext();
}
template <class E> E &Iterator<E>::next() {
if (!this->hasNext()) {
throw(IndexError("Out of bound!"));
}
E &temp = this->current->getContent();
this->current = this->current->getNextPtr();
return temp;
} }

View File

@@ -5,25 +5,19 @@
unsigned BaseRecord::nextRecordID = 1; unsigned BaseRecord::nextRecordID = 1;
std::string BaseRecord::cutToLength(std::string str, int length) const {
if (str.length() <= length) {
return str;
}
else {
return str.substr(0, length) + "+";
}
}
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),
studentNumber(_studentNumber), studentName(_studentName){}; student(_studentNumber, _studentName){};
BaseRecord::BaseRecord(const unsigned _recordID, const time_t _date, BaseRecord::BaseRecord(const unsigned _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),
studentNumber(_studentNumber), studentName(_studentName){}; student(_studentNumber, _studentName){};
BaseRecord::~BaseRecord() {
}
const unsigned BaseRecord::getRecordID() const { const unsigned BaseRecord::getRecordID() const {
return this->recordID; return this->recordID;
@@ -38,11 +32,11 @@ const std::string BaseRecord::getCourseName() const {
} }
const int BaseRecord::getStudentNumber() const { const int BaseRecord::getStudentNumber() const {
return this->studentNumber; return this->student.getNumber();
} }
const std::string BaseRecord::getStudentName() const { const std::string BaseRecord::getStudentName() const {
return this->studentName; return this->student.getName();
} }
void BaseRecord::promptForNewDate(bool showOriginal) { void BaseRecord::promptForNewDate(bool showOriginal) {
@@ -52,34 +46,35 @@ void BaseRecord::promptForNewDate(bool showOriginal) {
if (showOriginal) { if (showOriginal) {
char buffer[20]; char buffer[20];
strftime(buffer, 20, "%F", curDate); strftime(buffer, 20, "%F", curDate);
std::cout << setoutputcolor(green) << "Current date: " << buffer std::cout << setoutputcolor(ConsoleColorTool::green)
<< "Current date: " << buffer
<< ". Enter 0 to retain original value." << resetOutputColor << ". Enter 0 to retain original value." << resetOutputColor
<< std::endl; << std::endl;
std::cout << setoutputcolor(blue) << "Year: " << resetOutputColor std::cout << setoutputcolor(ConsoleColorTool::blue)
<< std::flush; << "Year: " << resetOutputColor << std::flush;
std::cin >> tempInput; std::cin >> tempInput;
curDate->tm_year = curDate->tm_year =
(tempInput == 0 ? curDate->tm_year : tempInput - 1900); (tempInput == 0 ? curDate->tm_year : tempInput - 1900);
std::cout << setoutputcolor(blue) << "Month: " << resetOutputColor std::cout << setoutputcolor(ConsoleColorTool::blue)
<< std::flush; << "Month: " << resetOutputColor << std::flush;
std::cin >> tempInput; std::cin >> tempInput;
curDate->tm_mon = (tempInput == 0 ? curDate->tm_mon : tempInput - 1); curDate->tm_mon = (tempInput == 0 ? curDate->tm_mon : tempInput - 1);
std::cout << setoutputcolor(blue) << "Day: " << resetOutputColor std::cout << setoutputcolor(ConsoleColorTool::blue)
<< std::flush; << "Day: " << resetOutputColor << std::flush;
std::cin >> tempInput; std::cin >> tempInput;
curDate->tm_mday = (tempInput == 0 ? curDate->tm_mday : tempInput); curDate->tm_mday = (tempInput == 0 ? curDate->tm_mday : tempInput);
} }
else { else {
std::cout << setoutputcolor(blue) << "Year: " << resetOutputColor std::cout << setoutputcolor(ConsoleColorTool::blue)
<< std::flush; << "Year: " << resetOutputColor << std::flush;
std::cin >> tempInput; std::cin >> tempInput;
curDate->tm_year = tempInput - 1900; curDate->tm_year = tempInput - 1900;
std::cout << setoutputcolor(blue) << "Month: " << resetOutputColor std::cout << setoutputcolor(ConsoleColorTool::blue)
<< std::flush; << "Month: " << resetOutputColor << std::flush;
std::cin >> tempInput; std::cin >> tempInput;
curDate->tm_mon = tempInput - 1; curDate->tm_mon = tempInput - 1;
std::cout << setoutputcolor(blue) << "Day: " << resetOutputColor std::cout << setoutputcolor(ConsoleColorTool::blue)
<< std::flush; << "Day: " << resetOutputColor << std::flush;
std::cin >> tempInput; std::cin >> tempInput;
curDate->tm_mday = tempInput; curDate->tm_mday = tempInput;
} }
@@ -88,10 +83,10 @@ void BaseRecord::promptForNewDate(bool showOriginal) {
void BaseRecord::promptForNewCourseName(bool showOriginal) { void BaseRecord::promptForNewCourseName(bool showOriginal) {
if (showOriginal) { if (showOriginal) {
std::cout << setoutputcolor(green) std::cout << setoutputcolor(ConsoleColorTool::green)
<< "Original course name: " << resetOutputColor << "Original course name: " << resetOutputColor
<< this->courseName << "\n" << this->courseName << "\n"
<< setoutputcolor(green) << setoutputcolor(ConsoleColorTool::green)
<< "Enter 0 to retain original value." << std::endl; << "Enter 0 to retain original value." << std::endl;
} }
std::cout << "Course name: " << std::flush; std::cout << "Course name: " << std::flush;
@@ -99,56 +94,86 @@ void BaseRecord::promptForNewCourseName(bool showOriginal) {
} }
void BaseRecord::promptForNewStudentInfo(bool showOriginal) { void BaseRecord::promptForNewStudentInfo(bool showOriginal) {
int tempStuID;
std::string tempStuName;
if (showOriginal) { if (showOriginal) {
int tempStuID; std::cout << setoutputcolor(ConsoleColorTool::green)
std::string tempStuName; << "Current student info: \n"
std::cout << setoutputcolor(green) << "Current student info: \n" << setoutputcolor(ConsoleColorTool::blue)
<< setoutputcolor(blue) << "Student ID: " << resetOutputColor << "Student ID: " << resetOutputColor
<< this->studentNumber << "\n" << this->student.getNumber() << "\n"
<< setoutputcolor(blue) << setoutputcolor(ConsoleColorTool::blue)
<< "Student Name: " << resetOutputColor << this->studentName << "Student Name: " << resetOutputColor
<< "\n" << this->student.getName() << "\n"
<< setoutputcolor(green) << setoutputcolor(ConsoleColorTool::green)
<< "Enter 0 to retain original value." << std::endl; << "Enter 0 to retain original value." << std::endl;
std::cout << setoutputcolor(blue) << "Student ID: " << resetOutputColor std::cout << setoutputcolor(ConsoleColorTool::blue)
<< std::flush; << "Student ID: " << resetOutputColor << std::flush;
std::cin >> tempStuID; std::cin >> tempStuID;
this->studentNumber = this->student.setNumber(tempStuID == 0 ? this->student.getNumber()
(tempStuID == 0 ? this->studentNumber : tempStuID); : tempStuID);
std::cout << setoutputcolor(blue) std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Studnet Name: " << resetOutputColor << std::flush; << "Student Name: " << resetOutputColor << std::flush;
std::cin >> tempStuName; std::cin >> tempStuName;
this->studentName = this->student.setName(tempStuName == "0" ? this->student.getName()
(tempStuName == "0" ? this->studentName : tempStuName); : tempStuName);
} }
else { else {
std::cout << setoutputcolor(blue) << "Student ID: " << resetOutputColor std::cout << setoutputcolor(ConsoleColorTool::blue)
<< std::flush; << "Student ID: " << resetOutputColor << std::flush;
std::cin >> this->studentNumber; std::cin >> tempStuID;
std::cout << setoutputcolor(blue) this->student.setNumber(tempStuID);
<< "Studnet Name: " << resetOutputColor << std::flush; std::cout << setoutputcolor(ConsoleColorTool::blue)
std::cin >> this->studentName; << "Student Name: " << resetOutputColor << std::flush;
std::cin >> tempStuName;
this->student.setName(tempStuName);
} }
} }
void BaseRecord::display() const { void BaseRecord::display() const {
std::cout << std::setfill('0') << std::setw(8) << this->recordID; std::cout << "" << std::setfill('0')
std::cout << " | "; << std::setw(recordDisplayRowSize.recordID - 2) << this->recordID;
std::cout << std::setfill(' ') << std::setw(12) std::cout << "";
<< this->cutToLength(this->date.toString(), 12); std::cout << std::setfill(' ') << std::setw(recordDisplayRowSize.date)
std::cout << " | "; << cutToLength(this->date.toString(), recordDisplayRowSize.date);
std::cout << std::setfill(' ') << std::setw(15) std::cout << "";
<< this->cutToLength(this->courseName, 15); std::cout << std::setfill(' ') << std::setw(recordDisplayRowSize.courseName)
std::cout << " | "; << cutToLength(this->courseName, recordDisplayRowSize.courseName);
std::cout << std::setfill(' ') << std::setw(10) << this->studentNumber; std::cout << "";
std::cout << " | "; std::cout << std::setfill(' ') << std::setw(recordDisplayRowSize.studentID)
std::cout << std::setfill(' ') << std::setw(15) << this->student.getNumber();
<< this->cutToLength(this->studentName, 15); std::cout << "";
std::cout << " | "; std::cout << std::setfill(' ')
std::cout << std::setfill(' ') << std::setw(10) << this->getRecordType(); << std::setw(recordDisplayRowSize.studentName)
<< cutToLength(this->student.getName(),
recordDisplayRowSize.studentName);
std::cout << "";
std::cout << std::setfill(' ') << std::setw(recordDisplayRowSize.type)
<< this->getRecordType() << "";
std::cout << std::endl; std::cout << std::endl;
} }
void BaseRecord::displayComplete() const {
std::cout << setoutputcolor(true) << setbgcolor(ConsoleColorTool::cyan)
<< "Record ID " << this->recordID << resetOutputColor << "\n";
std::cout << setoutputcolor(ConsoleColorTool::green)
<< "Date: " << resetOutputColor << this->date.toString() << "\n";
std::cout << setoutputcolor(ConsoleColorTool::green)
<< "Course name: " << resetOutputColor << this->courseName
<< "\n";
std::cout << setoutputcolor(ConsoleColorTool::green)
<< "Student: " << resetOutputColor << "\n";
std::cout << "├─" << setoutputcolor(ConsoleColorTool::blue)
<< "ID: " << resetOutputColor << this->student.getNumber()
<< "\n";
std::cout << "└─" << setoutputcolor(ConsoleColorTool::blue)
<< "Name: " << resetOutputColor << this->student.getName()
<< "\n";
std::cout << setoutputcolor(ConsoleColorTool::green)
<< "Type: " << resetOutputColor << this->getRecordType()
<< std::endl;
}
LateRecord::LateRecord(const time_t _date, const std::string _courseName, 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){};
@@ -162,6 +187,17 @@ std::string LateRecord::getRecordType() const {
return "Late"; return "Late";
} }
LateRecord::operator SaveRecord() const {
return SaveRecord{.recordID = this->recordID,
.date = this->date.getTime(),
.courseNameLength = this->courseName.length(),
.studentNumber = this->student.getNumber(),
.studentNameLength = this->student.getName().length(),
.recordType = StuRecord::Late};
}
LateRecord::~LateRecord(){};
AbsentRecord::AbsentRecord(const time_t _date, const std::string _courseName, AbsentRecord::AbsentRecord(const time_t _date, const std::string _courseName,
const int _studentNumber, const int _studentNumber,
const std::string _studentName) const std::string _studentName)
@@ -177,6 +213,17 @@ std::string AbsentRecord::getRecordType() const {
return "Absent"; return "Absent";
} }
AbsentRecord::operator SaveRecord() const {
return SaveRecord{.recordID = this->recordID,
.date = this->date.getTime(),
.courseNameLength = this->courseName.length(),
.studentNumber = this->student.getNumber(),
.studentNameLength = this->student.getName().length(),
.recordType = StuRecord::Absent};
}
AbsentRecord::~AbsentRecord(){};
PersonalLeaveRecord::PersonalLeaveRecord(const time_t _date, PersonalLeaveRecord::PersonalLeaveRecord(const time_t _date,
const std::string _courseName, const std::string _courseName,
const int _studentNumber, const int _studentNumber,
@@ -194,27 +241,13 @@ std::string PersonalLeaveRecord::getRecordType() const {
return "Personal"; return "Personal";
} }
SaveRecord::SaveRecord(const unsigned _recordID, const time_t _date, PersonalLeaveRecord::operator SaveRecord() const {
const std::string &courseName, const int _studentNumber, return SaveRecord{.recordID = this->recordID,
const std::string &studentName, RecordType _recordType) .date = this->date.getTime(),
: recordID(_recordID), date(_date), courseNameLength(courseName.length()), .courseNameLength = this->courseName.length(),
studentNumber(_studentNumber), studentNameLength(studentName.length()), .studentNumber = this->student.getNumber(),
recordType(_recordType){}; .studentNameLength = this->student.getName().length(),
.recordType = StuRecord::PersonalLeave};
}
BaseRecord *SaveRecord::convertToRecord(const char *_courseName, PersonalLeaveRecord::~PersonalLeaveRecord(){};
const char *_name) const {
switch (this->recordType) {
case Late:
return new LateRecord(this->recordID, this->date,
std::string(_courseName), this->studentNumber,
std::string(_name));
case Absent:
return new AbsentRecord(this->recordID, this->date,
std::string(_courseName), this->studentNumber,
std::string(_name));
case PersonalLeave:
return new PersonalLeaveRecord(this->recordID, this->date,
std::string(_courseName),
this->studentNumber, std::string(_name));
}
}

View File

@@ -1,5 +1,6 @@
#pragma once #pragma once
#include "Date.hpp" #include "Date.hpp"
#include "Student.hpp"
#include <ctime> #include <ctime>
/* /*
@@ -14,19 +15,33 @@ stduentName char[]
SaveRecord SaveRecord
courseName char[] courseName char[]
*/ */
const struct {
int recordID = 10;
int date = 10;
int courseName = 15;
int studentID = 10;
int studentName = 15;
int type = 10;
} recordDisplayRowSize;
namespace StuRecord {
enum RecordType { Late, Absent, PersonalLeave }; enum RecordType { Late, Absent, PersonalLeave };
};
struct SaveRecord {
unsigned recordID;
time_t date;
unsigned long courseNameLength;
int studentNumber;
unsigned long studentNameLength;
StuRecord::RecordType recordType;
};
class BaseRecord { class BaseRecord {
private: protected:
unsigned recordID; unsigned recordID;
Date date; Date date;
std::string courseName; std::string courseName;
int studentNumber; Student student;
std::string studentName;
// If the string is shorter than length, returns the string; if the string
// is longer than length, takes the first lenght - 1 letters and add a "+".
std::string cutToLength(std::string str, int length) const;
public: public:
static unsigned nextRecordID; static unsigned nextRecordID;
@@ -38,6 +53,7 @@ public:
BaseRecord(const unsigned _recordID, const time_t _date, BaseRecord(const unsigned _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();
const unsigned getRecordID() const; const unsigned getRecordID() const;
const Date &getDate() const; const Date &getDate() const;
const std::string getCourseName() const; const std::string getCourseName() const;
@@ -46,11 +62,12 @@ public:
void promptForNewDate(bool showOriginal = true); void promptForNewDate(bool showOriginal = true);
void promptForNewCourseName(bool showOriginal = true); void promptForNewCourseName(bool showOriginal = true);
void promptForNewStudentInfo(bool showOriginal = true); void promptForNewStudentInfo(bool showOriginal = true);
// Show the infomation in a line.
void display() const; void display() const;
// Show the infomation in multiple lines.
void displayComplete() const; void displayComplete() const;
const char *getCourseNameChar() const;
const char *getStudentNameChar() const;
virtual std::string getRecordType() const = 0; virtual std::string getRecordType() const = 0;
virtual operator SaveRecord() const = 0;
}; };
class LateRecord : public BaseRecord { class LateRecord : public BaseRecord {
@@ -60,7 +77,9 @@ public:
LateRecord(const unsigned _recordID, const time_t _date, LateRecord(const unsigned _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 std::string getRecordType() const; virtual std::string getRecordType() const;
virtual operator SaveRecord() const;
}; };
class AbsentRecord : public BaseRecord { class AbsentRecord : public BaseRecord {
@@ -70,7 +89,9 @@ public:
AbsentRecord(const unsigned _recordID, const time_t _date, AbsentRecord(const unsigned _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 std::string getRecordType() const; virtual std::string getRecordType() const;
virtual operator SaveRecord() const;
}; };
class PersonalLeaveRecord : public BaseRecord { class PersonalLeaveRecord : public BaseRecord {
@@ -81,23 +102,7 @@ public:
PersonalLeaveRecord(const unsigned _recordID, const time_t _date, PersonalLeaveRecord(const unsigned _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 std::string getRecordType() const; virtual std::string getRecordType() const;
}; virtual operator SaveRecord() const;
class SaveRecord {
private:
unsigned recordID;
time_t date;
int courseNameLength;
int studentNumber;
int studentNameLength;
RecordType recordType;
public:
SaveRecord() = delete;
SaveRecord(const unsigned _recordID, const time_t _date,
const std::string &courseName, const int _studentNumber,
const std::string &studentName, RecordType _recordType);
BaseRecord *convertToRecord(const char *_courseName,
const char *_name) const;
}; };

59
大作业/Student.cpp Normal file
View File

@@ -0,0 +1,59 @@
#include "Student.hpp"
Student::Student() : number(0), name(""), isAnyName(true), isAnyNumber(true) {};
Student::Student(const int _number, const std::string _name) : number(_number), name(_name), isAnyNumber(false), isAnyName(false) {};
const int Student::getNumber() const {
return this->number;
}
const std::string Student::getNumberString() const {
if (this->isAnyNumber) {
return "[Any]";
}
return std::to_string(this->number);
}
const std::string Student::getName() const {
if (this->isAnyName) {
return "[Any]";
}
return this->name;
}
void Student::setNumber(const int newNumber) {
this->isAnyNumber = false;
this->number = newNumber;
}
void Student::setName(const std::string newName) {
this->isAnyName = false;
this->name = newName;
}
void Student::setAnyNumber() {
this->isAnyNumber = true;
this->number = 0;
}
void Student::setAnyName() {
this->isAnyName = true;
this->name = "";
}
bool Student::matchesNumber(const Student &otherStu) const {
return this->isAnyNumber || this->number == otherStu.number;
}
bool Student::matchesName(const Student &otherStu) const {
return this->isAnyName || this->name == otherStu.name;
}
bool Student::matches(const Student &otherStu) const {
return this->matchesNumber(otherStu) && this->matchesName(otherStu);
}
bool Student::operator==(const Student &otherStu) const {
return this->matches(otherStu);
}

View File

@@ -4,19 +4,29 @@ class Student {
private: private:
int number; int number;
std::string name; std::string name;
bool isAnyNumber;
bool isAnyName;
public: public:
Student(); Student();
Student(const int _number, const std::string _name); Student(const int _number, const std::string _name);
Student(const Student &otherStudent);
// Return the student in format 'number name'.
std::string toString();
// Returns student number. // Returns student number.
int getNumber(); const int getNumber() const;
// Returns the string from of the number, so as to display "any"
const std::string getNumberString() const;
// Returns student name. // Returns student name.
std::string getName(); const std::string getName() const;
// Set the new name (especially when reading from file) // Set the new number
void setNumber(const int newNumber);
// Set the new name
void setName(const std::string newName); void setName(const std::string newName);
void setName(const char *newName); // Set the number to "any"
void setAnyNumber();
// Set the name to "any"
void setAnyName();
bool matchesNumber(const Student &otherStu) const;
bool matchesName(const Student &otherStu) const;
bool matches(const Student &otherStu) const;
bool operator==(const Student &otherStu) const;
}; };

View File

@@ -1,4 +1,5 @@
#include "Tools.hpp" #include "Tools.hpp"
using namespace ConsoleColorTool;
setoutputcolor::setoutputcolor(ConsoleColors _color) setoutputcolor::setoutputcolor(ConsoleColors _color)
: color(_color), bold(false){}; : color(_color), bold(false){};
@@ -30,6 +31,9 @@ std::ostream &operator<<(std::ostream &out, setoutputcolor setOutput) {
case green: case green:
out << ";32m"; out << ";32m";
break; break;
case brown:
out << ";33m";
break;
case blue: case blue:
out << ";34m"; out << ";34m";
break; break;
@@ -59,6 +63,9 @@ std::ostream &operator<<(std::ostream &out, setbgcolor setbg) {
case green: case green:
out << "\033[7;32m"; out << "\033[7;32m";
break; break;
case brown:
out << "\033[7;33m";
break;
case blue: case blue:
out << "\033[7;34m"; out << "\033[7;34m";
break; break;
@@ -84,4 +91,31 @@ setbgcolor::setbgcolor(ConsoleColors _color) : color(_color){};
std::ostream &resetOutputColor(std::ostream &out) { std::ostream &resetOutputColor(std::ostream &out) {
out << setoutputcolor(clear); out << setoutputcolor(clear);
return out; return out;
}
const std::string cutToLength(const std::string str, const int length) {
if (str.length() <= length) {
return str;
}
else {
return str.substr(0, length - 3) + "...";
}
}
const std::string setMiddle(const std::string str, const int targetLength, char fillChar) {
if (str.length() >= targetLength) {
return cutToLength(str, targetLength);
}
int left, right;
right = (targetLength - str.length()) / 2;
left = targetLength - str.length() - right;
std::string result;
for (int i = 0; i < left; i++) {
result += fillChar;
}
result += str;
for (int i = 0; i < right; i++) {
result += fillChar;
}
return result;
} }

View File

@@ -3,28 +3,46 @@
// Reference: https://cplusplus.com/forum/unices/36461/ // Reference: https://cplusplus.com/forum/unices/36461/
enum ConsoleColors { black, red, green, blue, magenta, cyan, lightGray, clear }; namespace ConsoleColorTool {
enum ConsoleColors {
black,
red,
green,
brown,
blue,
magenta,
cyan,
lightGray,
clear
};
};
class setoutputcolor { class setoutputcolor {
private: private:
ConsoleColors color; ConsoleColorTool::ConsoleColors color;
bool bold; bool bold;
friend std::ostream &operator<<(std::ostream &out, friend std::ostream &operator<<(std::ostream &out,
setoutputcolor setOutput); setoutputcolor setOutput);
public: public:
setoutputcolor(ConsoleColors _color); setoutputcolor(ConsoleColorTool::ConsoleColors _color);
setoutputcolor(bool bold); setoutputcolor(bool bold);
setoutputcolor(ConsoleColors _color, bool bold); setoutputcolor(ConsoleColorTool::ConsoleColors _color, bool bold);
}; };
class setbgcolor { class setbgcolor {
private: private:
ConsoleColors color; ConsoleColorTool::ConsoleColors color;
friend std::ostream &operator<<(std::ostream &out, setbgcolor setbg); friend std::ostream &operator<<(std::ostream &out, setbgcolor setbg);
public: public:
setbgcolor(ConsoleColors _color); setbgcolor(ConsoleColorTool::ConsoleColors _color);
}; };
std::ostream &resetOutputColor(std::ostream &out); std::ostream &resetOutputColor(std::ostream &out);
// If the string is shorter than length, returns the string; if the string
// is longer than length, takes the first lenght - 1 letters and add a "+".
const std::string cutToLength(const std::string str, const int length);
const std::string setMiddle(const std::string str, const int targetLength, char fillChar = ' ');

View File

@@ -1,8 +1,9 @@
#include "ListDisplay.hpp"
#include "ListE.hpp" #include "ListE.hpp"
#include "Tools.hpp"
#include "Record.hpp" #include "Record.hpp"
#include <iostream> #include "Tools.hpp"
#include <iomanip> #include <iomanip>
#include <iostream>
template <class E> void display(List<E> list) { template <class E> void display(List<E> list) {
for (int i = 0; i < list.length(); i++) { for (int i = 0; i < list.length(); i++) {
@@ -25,12 +26,12 @@ int main() {
aList.swap(0, 3); aList.swap(0, 3);
display(aList); display(aList);
// aList.sort([=](const int &a, const int &b) { return a > b; }); // aList.sort([](const int &a, const int &b) { return a > b; });
// display(aList); // display(aList);
List<int> bList = List<int> bList =
aList.sorted([=](const int &a, const int &b) { return a > b; }); aList.sorted([](const int &a, const int &b) { return a > b; });
display(bList); display(bList);
@@ -38,17 +39,34 @@ int main() {
display(bList); display(bList);
bList.filter([=](const int &a) { return a > 6; }); bList.filter([](const int &a) { return a > 6; });
display(bList); display(bList);
std::cout << "hhh" << setoutputcolor(blue, true) << "aaa" << setoutputcolor(blue, false) << "bbb" << resetOutputColor << std::endl; std::cout << "hhh" << setoutputcolor(ConsoleColorTool::blue, true) << "aaa"
LateRecord la(125534456, "SomeCourse", 10821398, "SomeStu"); << setoutputcolor(ConsoleColorTool::blue, false) << "bbb"
AbsentRecord lb(2874238743, "SomeotherCourse", 10239944, "SomeotherStu"); << resetOutputColor << std::endl;
LateRecord la(125534456, "SomeCourselonglonglonglonglong", 10821398, "SomeStu");
AbsentRecord lb(2874238743, "SomeOtherCourse", 10239944, "SomeotherStu");
la.display(); la.display();
std::cout << setbgcolor(lightGray); std::cout << setbgcolor(ConsoleColorTool::lightGray);
lb.display(); lb.display();
std::cout << resetOutputColor; std::cout << resetOutputColor;
la.promptForNewStudentInfo(); // la.promptForNewStudentInfo();
la.display();
// la.display();
la.displayComplete();
std::cout << "------------" << std::endl;
List<BaseRecord *> recordPtrList;
recordPtrList.append(new LateRecord(122333, "hhhh", 10394, "aneiei"));
recordPtrList.append(new AbsentRecord(123994994, "aadkfk", 129939948, "adiorrr"));
recordPtrList.append(new PersonalLeaveRecord(132934949, "mumu", 129293, "s999"));
ListDisplay displayer(recordPtrList);
displayer.display();
Iterator<BaseRecord *> it = recordPtrList.iterate();
while (it) {
delete it.next();
}
return 0; return 0;
} }