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

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

View File

@@ -1,21 +1,75 @@
#include "ListDisplay.hpp"
#include "Exceptions.hpp"
#include "Tools.hpp"
#include <iomanip>
ListDisplay::ListDisplay(const List<BaseRecord> &_allRecords)
: allRecords(_allRecords), fromDate(), toDate(), recordNumPerPage(20),
currentPage(1), totalPage(allRecords.length() / recordNumPerPage + 1),
sortOrder(ASCENT), sortByProp(RecordID){};
ListDisplay::ListDisplay(const List<BaseRecord *> &_allRecordsPtrList)
: allRecordsPtrList(_allRecordsPtrList), fromDate(), toDate(),
searchForStu(), recordNumPerPage(20), currentPageIndex(0),
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() {
return currentPage < totalPage;
return currentPageIndex < maxPageIndex;
}
bool ListDisplay::hasPrev() {
return currentPage > 1;
return currentPageIndex > 0;
}
void ListDisplay::displayNext() {
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 {
private:
const List<BaseRecord> &allRecords;
List<BaseRecord> filteredRecords;
const List<BaseRecord*> &allRecordsPtrList;
List<BaseRecord*> filteredRecordsPtrList;
Date fromDate;
Date toDate;
Student searchForStu;
int recordNumPerPage;
int currentPage;
int totalPage;
// The current page index, starting from 0
int currentPageIndex;
int maxPageIndex;
bool sortOrder;
SortBy sortByProp;
const std::string tableTitleRow;
public:
ListDisplay() = delete;
ListDisplay(const List<BaseRecord> &_allRecords);
ListDisplay(const List<BaseRecord*> &_allRecordsPtrList);
bool hasNext();
bool hasPrev();
void displayNext();

View File

@@ -33,9 +33,6 @@ public:
// Swap the element located at index a and b. Throws IndexError if the given
// index is beyond length of the list.
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);
const E &operator[](const int index) const;
List<E> &operator=(const List<E> &otherList);
@@ -51,10 +48,15 @@ public:
// Only retain item that matches the isTargetFunc
List<E> &filter(std::function<bool(const E &)> const &isTargetFunc);
// 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.
const List<E> sorted(std::function<bool(const E &, const E &)> const
&isCorrectOrderFunc) const;
Iterator<E> &&iterate();
Iterator<E> &&iterate(int index);
};
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() {
if (this->_length == 0) {
return *this;
}
this->head->destruct();
this->head = NULL;
this->_length = 0;
@@ -266,12 +271,13 @@ template <class E> List<E> &List<E>::operator=(const List<E> &otherList) {
if (otherList.length() > 0) {
this->head = new Node<E>(otherList[0]);
this->_length = 1;
Node<E> *nextPtr = otherList->head->getNextPtr();
Node<E> *nextPtr = otherList.head->getNextPtr();
while (nextPtr != NULL) {
this->append((*nextPtr).getContent());
nextPtr = (*nextPtr).getNextPtr();
}
}
return *this;
}
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;
while(current->getNextPtr() != NULL) {
while (current->getNextPtr() != NULL) {
if (!isTargetFunc(current->getNextPtr()->getContent())) {
Node<E> *newNext = current->getNextPtr()->getNextPtr();
delete current->getNextPtr();
@@ -354,7 +360,8 @@ List<E> &List<E>::filter(std::function<bool(const E &)> const &isTargetFunc) {
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);
}
@@ -363,3 +370,17 @@ const List<E> List<E>::sorted(
std::function<bool(const E &, const E &)> const &isCorrectOrderFunc) const {
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
main.o: main.cpp
@@ -17,3 +17,9 @@ Date.o: Date.cpp
Tools.o: Tools.cpp
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();
};
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>
@@ -73,3 +85,22 @@ template <class E> void Node<E>::destruct() {
}
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;
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,
const int _studentNumber, const std::string _studentName)
: recordID(nextRecordID++), date(_date), courseName(_courseName),
studentNumber(_studentNumber), studentName(_studentName){};
student(_studentNumber, _studentName){};
BaseRecord::BaseRecord(const unsigned _recordID, const time_t _date,
const std::string _courseName, const int _studentNumber,
const std::string _studentName)
: recordID(_recordID), date(_date), courseName(_courseName),
studentNumber(_studentNumber), studentName(_studentName){};
student(_studentNumber, _studentName){};
BaseRecord::~BaseRecord() {
}
const unsigned BaseRecord::getRecordID() const {
return this->recordID;
@@ -38,11 +32,11 @@ const std::string BaseRecord::getCourseName() const {
}
const int BaseRecord::getStudentNumber() const {
return this->studentNumber;
return this->student.getNumber();
}
const std::string BaseRecord::getStudentName() const {
return this->studentName;
return this->student.getName();
}
void BaseRecord::promptForNewDate(bool showOriginal) {
@@ -52,34 +46,35 @@ void BaseRecord::promptForNewDate(bool showOriginal) {
if (showOriginal) {
char buffer[20];
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
<< std::endl;
std::cout << setoutputcolor(blue) << "Year: " << resetOutputColor
<< std::flush;
std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Year: " << resetOutputColor << std::flush;
std::cin >> tempInput;
curDate->tm_year =
(tempInput == 0 ? curDate->tm_year : tempInput - 1900);
std::cout << setoutputcolor(blue) << "Month: " << resetOutputColor
<< std::flush;
std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Month: " << resetOutputColor << std::flush;
std::cin >> tempInput;
curDate->tm_mon = (tempInput == 0 ? curDate->tm_mon : tempInput - 1);
std::cout << setoutputcolor(blue) << "Day: " << resetOutputColor
<< std::flush;
std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Day: " << resetOutputColor << std::flush;
std::cin >> tempInput;
curDate->tm_mday = (tempInput == 0 ? curDate->tm_mday : tempInput);
}
else {
std::cout << setoutputcolor(blue) << "Year: " << resetOutputColor
<< std::flush;
std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Year: " << resetOutputColor << std::flush;
std::cin >> tempInput;
curDate->tm_year = tempInput - 1900;
std::cout << setoutputcolor(blue) << "Month: " << resetOutputColor
<< std::flush;
std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Month: " << resetOutputColor << std::flush;
std::cin >> tempInput;
curDate->tm_mon = tempInput - 1;
std::cout << setoutputcolor(blue) << "Day: " << resetOutputColor
<< std::flush;
std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Day: " << resetOutputColor << std::flush;
std::cin >> tempInput;
curDate->tm_mday = tempInput;
}
@@ -88,10 +83,10 @@ void BaseRecord::promptForNewDate(bool showOriginal) {
void BaseRecord::promptForNewCourseName(bool showOriginal) {
if (showOriginal) {
std::cout << setoutputcolor(green)
std::cout << setoutputcolor(ConsoleColorTool::green)
<< "Original course name: " << resetOutputColor
<< this->courseName << "\n"
<< setoutputcolor(green)
<< setoutputcolor(ConsoleColorTool::green)
<< "Enter 0 to retain original value." << std::endl;
}
std::cout << "Course name: " << std::flush;
@@ -99,56 +94,86 @@ void BaseRecord::promptForNewCourseName(bool showOriginal) {
}
void BaseRecord::promptForNewStudentInfo(bool showOriginal) {
if (showOriginal) {
int tempStuID;
std::string tempStuName;
std::cout << setoutputcolor(green) << "Current student info: \n"
<< setoutputcolor(blue) << "Student ID: " << resetOutputColor
<< this->studentNumber << "\n"
<< setoutputcolor(blue)
<< "Student Name: " << resetOutputColor << this->studentName
<< "\n"
<< setoutputcolor(green)
if (showOriginal) {
std::cout << setoutputcolor(ConsoleColorTool::green)
<< "Current student info: \n"
<< setoutputcolor(ConsoleColorTool::blue)
<< "Student ID: " << resetOutputColor
<< this->student.getNumber() << "\n"
<< setoutputcolor(ConsoleColorTool::blue)
<< "Student Name: " << resetOutputColor
<< this->student.getName() << "\n"
<< setoutputcolor(ConsoleColorTool::green)
<< "Enter 0 to retain original value." << std::endl;
std::cout << setoutputcolor(blue) << "Student ID: " << resetOutputColor
<< std::flush;
std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Student ID: " << resetOutputColor << std::flush;
std::cin >> tempStuID;
this->studentNumber =
(tempStuID == 0 ? this->studentNumber : tempStuID);
std::cout << setoutputcolor(blue)
<< "Studnet Name: " << resetOutputColor << std::flush;
this->student.setNumber(tempStuID == 0 ? this->student.getNumber()
: tempStuID);
std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Student Name: " << resetOutputColor << std::flush;
std::cin >> tempStuName;
this->studentName =
(tempStuName == "0" ? this->studentName : tempStuName);
this->student.setName(tempStuName == "0" ? this->student.getName()
: tempStuName);
}
else {
std::cout << setoutputcolor(blue) << "Student ID: " << resetOutputColor
<< std::flush;
std::cin >> this->studentNumber;
std::cout << setoutputcolor(blue)
<< "Studnet Name: " << resetOutputColor << std::flush;
std::cin >> this->studentName;
std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Student ID: " << resetOutputColor << std::flush;
std::cin >> tempStuID;
this->student.setNumber(tempStuID);
std::cout << setoutputcolor(ConsoleColorTool::blue)
<< "Student Name: " << resetOutputColor << std::flush;
std::cin >> tempStuName;
this->student.setName(tempStuName);
}
}
void BaseRecord::display() const {
std::cout << std::setfill('0') << std::setw(8) << this->recordID;
std::cout << " | ";
std::cout << std::setfill(' ') << std::setw(12)
<< this->cutToLength(this->date.toString(), 12);
std::cout << " | ";
std::cout << std::setfill(' ') << std::setw(15)
<< this->cutToLength(this->courseName, 15);
std::cout << " | ";
std::cout << std::setfill(' ') << std::setw(10) << this->studentNumber;
std::cout << " | ";
std::cout << std::setfill(' ') << std::setw(15)
<< this->cutToLength(this->studentName, 15);
std::cout << " | ";
std::cout << std::setfill(' ') << std::setw(10) << this->getRecordType();
std::cout << "" << std::setfill('0')
<< std::setw(recordDisplayRowSize.recordID - 2) << this->recordID;
std::cout << "";
std::cout << std::setfill(' ') << std::setw(recordDisplayRowSize.date)
<< cutToLength(this->date.toString(), recordDisplayRowSize.date);
std::cout << "";
std::cout << std::setfill(' ') << std::setw(recordDisplayRowSize.courseName)
<< cutToLength(this->courseName, recordDisplayRowSize.courseName);
std::cout << "";
std::cout << std::setfill(' ') << std::setw(recordDisplayRowSize.studentID)
<< this->student.getNumber();
std::cout << "";
std::cout << std::setfill(' ')
<< 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;
}
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,
const int _studentNumber, const std::string _studentName)
: BaseRecord(_date, _courseName, _studentNumber, _studentName){};
@@ -162,6 +187,17 @@ std::string LateRecord::getRecordType() const {
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,
const int _studentNumber,
const std::string _studentName)
@@ -177,6 +213,17 @@ std::string AbsentRecord::getRecordType() const {
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,
const std::string _courseName,
const int _studentNumber,
@@ -194,27 +241,13 @@ std::string PersonalLeaveRecord::getRecordType() const {
return "Personal";
}
SaveRecord::SaveRecord(const unsigned _recordID, const time_t _date,
const std::string &courseName, const int _studentNumber,
const std::string &studentName, RecordType _recordType)
: recordID(_recordID), date(_date), courseNameLength(courseName.length()),
studentNumber(_studentNumber), studentNameLength(studentName.length()),
recordType(_recordType){};
BaseRecord *SaveRecord::convertToRecord(const char *_courseName,
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));
}
PersonalLeaveRecord::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::PersonalLeave};
}
PersonalLeaveRecord::~PersonalLeaveRecord(){};

View File

@@ -1,5 +1,6 @@
#pragma once
#include "Date.hpp"
#include "Student.hpp"
#include <ctime>
/*
@@ -14,19 +15,33 @@ stduentName char[]
SaveRecord
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 };
};
struct SaveRecord {
unsigned recordID;
time_t date;
unsigned long courseNameLength;
int studentNumber;
unsigned long studentNameLength;
StuRecord::RecordType recordType;
};
class BaseRecord {
private:
protected:
unsigned recordID;
Date date;
std::string courseName;
int studentNumber;
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;
Student student;
public:
static unsigned nextRecordID;
@@ -38,6 +53,7 @@ public:
BaseRecord(const unsigned _recordID, const time_t _date,
const std::string _courseName, const int _studentNumber,
const std::string _studentName);
virtual ~BaseRecord();
const unsigned getRecordID() const;
const Date &getDate() const;
const std::string getCourseName() const;
@@ -46,11 +62,12 @@ public:
void promptForNewDate(bool showOriginal = true);
void promptForNewCourseName(bool showOriginal = true);
void promptForNewStudentInfo(bool showOriginal = true);
// Show the infomation in a line.
void display() const;
// Show the infomation in multiple lines.
void displayComplete() const;
const char *getCourseNameChar() const;
const char *getStudentNameChar() const;
virtual std::string getRecordType() const = 0;
virtual operator SaveRecord() const = 0;
};
class LateRecord : public BaseRecord {
@@ -60,7 +77,9 @@ public:
LateRecord(const unsigned _recordID, const time_t _date,
const std::string _courseName, const int _studentNumber,
const std::string _studentName);
virtual ~LateRecord();
virtual std::string getRecordType() const;
virtual operator SaveRecord() const;
};
class AbsentRecord : public BaseRecord {
@@ -70,7 +89,9 @@ public:
AbsentRecord(const unsigned _recordID, const time_t _date,
const std::string _courseName, const int _studentNumber,
const std::string _studentName);
virtual ~AbsentRecord();
virtual std::string getRecordType() const;
virtual operator SaveRecord() const;
};
class PersonalLeaveRecord : public BaseRecord {
@@ -81,23 +102,7 @@ public:
PersonalLeaveRecord(const unsigned _recordID, const time_t _date,
const std::string _courseName, const int _studentNumber,
const std::string _studentName);
virtual ~PersonalLeaveRecord();
virtual std::string getRecordType() 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;
virtual operator SaveRecord() 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:
int number;
std::string name;
bool isAnyNumber;
bool isAnyName;
public:
Student();
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.
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.
std::string getName();
// Set the new name (especially when reading from file)
const std::string getName() const;
// Set the new number
void setNumber(const int newNumber);
// Set the new name
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"
using namespace ConsoleColorTool;
setoutputcolor::setoutputcolor(ConsoleColors _color)
: color(_color), bold(false){};
@@ -30,6 +31,9 @@ std::ostream &operator<<(std::ostream &out, setoutputcolor setOutput) {
case green:
out << ";32m";
break;
case brown:
out << ";33m";
break;
case blue:
out << ";34m";
break;
@@ -59,6 +63,9 @@ std::ostream &operator<<(std::ostream &out, setbgcolor setbg) {
case green:
out << "\033[7;32m";
break;
case brown:
out << "\033[7;33m";
break;
case blue:
out << "\033[7;34m";
break;
@@ -85,3 +92,30 @@ std::ostream &resetOutputColor(std::ostream &out) {
out << setoutputcolor(clear);
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/
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 {
private:
ConsoleColors color;
ConsoleColorTool::ConsoleColors color;
bool bold;
friend std::ostream &operator<<(std::ostream &out,
setoutputcolor setOutput);
public:
setoutputcolor(ConsoleColors _color);
setoutputcolor(ConsoleColorTool::ConsoleColors _color);
setoutputcolor(bool bold);
setoutputcolor(ConsoleColors _color, bool bold);
setoutputcolor(ConsoleColorTool::ConsoleColors _color, bool bold);
};
class setbgcolor {
private:
ConsoleColors color;
ConsoleColorTool::ConsoleColors color;
friend std::ostream &operator<<(std::ostream &out, setbgcolor setbg);
public:
setbgcolor(ConsoleColors _color);
setbgcolor(ConsoleColorTool::ConsoleColors _color);
};
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 "Tools.hpp"
#include "Record.hpp"
#include <iostream>
#include "Tools.hpp"
#include <iomanip>
#include <iostream>
template <class E> void display(List<E> list) {
for (int i = 0; i < list.length(); i++) {
@@ -25,12 +26,12 @@ int main() {
aList.swap(0, 3);
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);
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);
@@ -38,17 +39,34 @@ int main() {
display(bList);
bList.filter([=](const int &a) { return a > 6; });
bList.filter([](const int &a) { return a > 6; });
display(bList);
std::cout << "hhh" << setoutputcolor(blue, true) << "aaa" << setoutputcolor(blue, false) << "bbb" << resetOutputColor << std::endl;
LateRecord la(125534456, "SomeCourse", 10821398, "SomeStu");
AbsentRecord lb(2874238743, "SomeotherCourse", 10239944, "SomeotherStu");
std::cout << "hhh" << setoutputcolor(ConsoleColorTool::blue, true) << "aaa"
<< setoutputcolor(ConsoleColorTool::blue, false) << "bbb"
<< resetOutputColor << std::endl;
LateRecord la(125534456, "SomeCourselonglonglonglonglong", 10821398, "SomeStu");
AbsentRecord lb(2874238743, "SomeOtherCourse", 10239944, "SomeotherStu");
la.display();
std::cout << setbgcolor(lightGray);
std::cout << setbgcolor(ConsoleColorTool::lightGray);
lb.display();
std::cout << resetOutputColor;
la.promptForNewStudentInfo();
la.display();
// la.promptForNewStudentInfo();
// 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;
}