2017中山大學軟體工程初級實訓
阿新 • • 發佈:2019-02-14
這次,還是一樣,初級實訓需要完成一個Agenda系統,同樣的,需求我們可以參考wiki
使用者名稱與密碼均為guest
簡述:
1。 階段一實現Date類,Meeting類,User類,Storage類。
2。 階段二實現AgendaService類,簡易的UI類。
3。 階段三實現擴充套件內容
簡述各階段:
1。 階段一:做Agenda的最底層,其中最應該注意的是Date類與Storage類,都有一定的坑。
2。 階段二:做AgendaService類,這裡就是各種邊界值的考慮,UI類基本就是碼字,沒有什麼難的。
3。 階段三:這裡就是發揮自己的想象力的時候,我是寫shell指令碼,用dialog工具做圖形化介面,用txt檔案作為shell指令碼與c++中互相”通訊”的跳板。並通過並行處理來做背景音樂的效果,播放音樂用的是sox,最後修改bashrc檔案,來將Agenda作為系統命令。這裡舍友想參加,我就讓他寫了一個系統資訊的展示欄作為選單選項。
由於階段二還有一兩個小bug,現在沒有時間去處理,所以階段二程式碼不展示。
階段三做完,已經滿分了,所以階段二也沒有修改。
話不多說,熟悉我的部落格的人會知道。程式碼是主要組成部分。
相關程式碼,測試檔案,指令碼下載
傳送門
//Date.hpp
#ifndef DATE_H
#define DATE_H
#include <initializer_list>
#include <string>
class Date {
public:
/**
* @brief default constructor
*/
Date();
/**
* @brief constructor with arguments
*/
Date(int t_year, int t_month, int t_day, int t_hour, int t_minute);
/**
* @brief constructor with a string
*/
Date(const std::string &dateString);
/**
* @brief return the year of a Date
* @return a integer indicate the year of a date
*/
int getYear(void) const;
/**
* @brief set the year of a date
* @param a integer indicate the new year of a date
*/
void setYear(const int t_year);
/**
* @brief return the month of a Date
* @return a integer indicate the month of a date
*/
int getMonth(void) const;
/**
* @brief set the month of a date
* @param a integer indicate the new month of a date
*/
void setMonth(const int t_month);
/**
* @brief return the day of a Date
* @return a integer indicate the day of a date
*/
int getDay(void) const;
/**
* @brief set the day of a date
* @param a integer indicate the new day of a date
*/
void setDay(const int t_day);
/**
* @brief return the hour of a Date
* @return a integer indicate the hour of a date
*/
int getHour(void) const;
/**
* @brief set the hour of a date
* @param a integer indicate the new hour of a date
*/
void setHour(const int t_hour);
/**
* @brief return the minute of a Date
* @return a integer indicate the minute of a date
*/
int getMinute(void) const;
/**
* @brief set the minute of a date
* @param a integer indicate the new minute of a date
*/
void setMinute(const int t_minute);
/**
* @brief check whether the date is valid or not
* @return the bool indicate valid or not
*/
static bool isValid(const Date &t_date);
/**
* @brief convert a string to date, if the format is not correct return
* 0000-00-00/00:00
* @return a date
*/
static Date stringToDate(const std::string &t_dateString);
/**
* @brief convert a date to string, if the date is invalid return
* 0000-00-00/00:00
*/
static std::string dateToString(const Date &t_date);
/**
* @brief overload the assign operator
*/
Date &operator=(const Date &t_date);
/**
* @brief check whether the CurrentDate is equal to the t_date
*/
bool operator==(const Date &t_date) const;
/**
* @brief check whether the CurrentDate is greater than the t_date
*/
bool operator>(const Date &t_date) const;
/**
* @brief check whether the CurrentDate is less than the t_date
*/
bool operator<(const Date &t_date) const;
/**
* @brief check whether the CurrentDate is greater or equal than the t_date
*/
bool operator>=(const Date &t_date) const;
/**
* @brief check whether the CurrentDate is less than or equal to the t_date
*/
bool operator<=(const Date &t_date) const;
private:
int m_year;
int m_month;
int m_day;
int m_hour;
int m_minute;
};
#endif
//Date.cpp
#include<iostream>
#include"Date.hpp"
#include<math.h>
#include<string>
#include<vector>
using namespace std;
bool isLeap(int testYear){
if(testYear % 4 == 0 && testYear % 100 != 0)
return true;
if(testYear % 400 == 0)
return true;
return false;
}
void push_str_int(string& str , int num){
int temp = num ;
if(num == 0)
{
str.push_back('0');
}
vector<int> v;
while(temp != 0){
int doc = temp % 10;
v.push_back(doc);
temp /= 10;
}
int len = v.size();
for(int index = 0 ; index < len ; index++)
{
str.push_back('0' + v[len-1-index]);
}
}
void initial(string& str , int num , int s){
if(s == 4){
int count = 3;
while(pow(10,count--) > num)
str.push_back('0');
push_str_int(str,num);
}
if(s == 2){
if(num < 10)
str.push_back('0');
push_str_int(str,num);
}
}
int str_int(string& str){
int len = str.size();
int count = 0;
for(int index = 0 ; index < len ; index++)
{
count += (str[index] - '0');
if(index != len - 1)
count *= 10;
}
return count;
}
bool valid(int y , int m , int d )
{
if(y < 1000 || y > 9999)
{ //cout<<y<<" "<<m<<" "<<d<<endl;
// cout<<"wrong"<<endl;
return false;}
bool flag = isLeap(y);
int array1[12] = {31,28,31,30,31,30,31,31,30,31,30,31};
int array2[12] = {31,29,31,30,31,30,31,31,30,31,30,31};
if(flag == false){
if(m > 0 && m < 13 && d <= array1[m-1] && d > 0)
return true;
else
{
// cout<<"wrong"<<endl;
return false;}
}
else{
if(m > 0 && m < 13 && d <= array2[m-1] && d > 0)
return true;
else
return false;
}
}
Date::Date(){
m_year = 0;
m_month = 0;
m_day = 0;
m_hour = 0;
m_minute = 0;
}
Date::Date(int t_y, int t_mo , int t_d , int t_h , int t_mi)
{
m_year = t_y;
m_month = t_mo;
m_day = t_d;
m_hour = t_h;
m_minute = t_mi;
}
bool valid_str(const string& str)
{
int len = str.size();
if(len != 16)
return false;
if(str[4] != '-')
return false;
if(str[7] != '-')
return false;
if(str[10] != '/')
return false;
if(str[13] != ':')
return false;
// cout<<"no"<<str<<endl;
for(int index = 0 ; index < 4 ; index++)
{
if(str[index] < '0' || str[index] > '9')
return false;
}
// cout<<"1no "<<str<<endl;
for(int index = 5 ; index < 7 ; index++)
{
if(str[index] < '0' || str[index] > '9')
return false;
}
//cout<<"2no "<<str<<endl;
for(int index = 8 ; index < 10 ; index++)
{
if(str[index] < '0' || str[index] > '9')
return false;
}
//cout<<"3no "<<str<<endl;
for(int index = 11 ; index < 13 ; index++)
{
if(str[index] < '0' || str[index] > '9')
return false;
}
//cout<<"4no "<<str<<endl;
for(int index = 14 ; index < 16 ; index++)
{
if(str[index] < '0' || str[index] > '9')
return false;
}
// cout<<"5no "<<str<<endl;
return true;
}
Date::Date(const string& data){
string str;
if(valid_str(data) == false)
{
this->m_year = 0;
this->m_month = 0;
this->m_day = 0;
this->m_hour = 0;
this->m_minute = 0;
}
else{
for(int index = 0 ; index < 4 ; index++)
str.push_back(data[index]);
m_year = str_int(str);
str.clear();
for(int index = 5 ; index <= 6 ; index++)
str.push_back(data[index]);
m_month = str_int(str);
str.clear();
for(int index = 8 ; index <= 9 ; index++)
str.push_back(data[index]);
m_day = str_int(str);
str.clear();
for(int index = 11 ; index <= 12 ; index++)
str.push_back(data[index]);
m_hour = str_int(str);
str.clear();
for(int index = 14 ; index <= 15 ; index++)
str.push_back(data[index]);
m_minute = str_int(str);
str.clear();
}
}
int Date::getYear(void) const
{
return m_year;
}
void Date::setYear(const int t_y){
m_year = t_y;
}
int Date::getMonth(void) const
{
return m_month;
}
void Date::setMonth(const int t_m)
{
m_month = t_m;
}
int Date::getDay(void) const
{
return m_day;
}
void Date::setDay(const int t_d)
{
m_day = t_d;
}
int Date::getHour(void) const
{
return m_hour;
}
void Date::setHour(const int t_h)
{
m_hour = t_h;
}
int Date::getMinute(void) const
{
return m_minute;
}
void Date::setMinute(const int t_m)
{
m_minute = t_m;
}
bool Date::isValid(const Date& test)
{
bool flag1 = valid(test.m_year , test.m_month, test.m_day);
if(flag1 == false)
{
// cout<<"year wronf"<<endl;
return false;}
if(test.m_hour < 0 || test.m_hour >= 24 )
return false;
if(test.m_minute < 0 || test.m_minute >= 60)
return false;
return true;
}
Date Date::stringToDate(const string& str)
{ bool flag = valid_str(str);
if(flag == false)
{
// string ptr = "0000-00-00/00:00";
Date temp(0,0,0,0,0);
return temp;
}
Date temp(str);
return temp;
}
string Date::dateToString(const Date& data)
{ if(data.isValid(data) ==false)
{
string str = "0000-00-00/00:00";
return str;
}
string str;
initial(str,data.m_year,4);
str.push_back('-');
initial(str,data.m_month,2);
str.push_back('-');
initial(str,data.m_day,2);
str.push_back('/');
initial(str,data.m_hour,2);
str.push_back(':');
initial(str,data.m_minute,2);
return str;
}
Date& Date::operator=(const Date &other)
{
m_year = other.m_year;
m_month = other.m_month;
m_day = other.m_day;
m_hour = other.m_hour;
m_minute = other.m_minute;
return *this;
}
bool Date::operator==(const Date& other) const
{
if(m_year != other.m_year || m_month != other.m_month)
return false;
if(m_day != other.m_day || m_hour != other.m_hour)
return false;
if(m_minute != other.m_minute)
return false;
return true;
}
bool Date::operator<(const Date& other) const
{
if(m_year < other.m_year)
return true;
if(m_year > other.m_year)
return false;
if(m_month < other.m_month)
return true;
if(m_month > other.m_month)
return false;
if(m_day < other.m_day)
return true;
if(m_day > other.m_day)
return false;
if(m_hour < other.m_hour)
return true;
if(m_hour > other.m_hour)
return false;
if(m_minute < other.m_minute)
return true;
return false;
}
bool Date::operator>(const Date& other) const
{
bool flag1 = (*this == other);
bool flag2 = (*this < other);
if(flag1 == false && flag2 == false)
return true;
return false;
}
bool Date::operator>=(const Date& other) const
{
bool flag1 = (*this < other);
if(flag1 == false)
return true;
return false;
}
bool Date::operator<=(const Date& other) const
{
bool flag1 = (*this > other);
if(flag1 == false)
return true;
return false;
}
//User.hpp
#ifndef USER_H
#define USER_H
#include <initializer_list>
#include <string>
class User {
public:
/**
* @brief the default constructor
*/
User() = default;
/**
* constructor with arguments
*/
User(const std::string &t_userName, const std::string &t_userPassword,
const std::string &t_userEmail, const std::string &t_userPhone);
/**
* @brief copy constructor
*/
User(const User &t_user);
/**
* @brief get the name of the user
* @return return a string indicate the name of the user
*/
std::string getName() const;
/**
* @brief set the name of the user
* @param a string indicate the new name of the user
*/
void setName(const std::string &t_name);
/**
* @brief get the password of the user
* @return return a string indicate the password of the user
*/
std::string getPassword() const;
/**
* @brief set the password of the user
* @param a string indicate the new password of the user
*/
void setPassword(const std::string &t_password);
/**
* @brief get the email of the user
* @return return a string indicate the email of the user
*/
std::string getEmail() const;
/**
* @brief set the email of the user
* @param a string indicate the new email of the user
*/
void setEmail(const std::string &t_email);
/**
* @brief get the phone of the user
* @return return a string indicate the phone of the user
*/
std::string getPhone() const;
/**
* @brief set the phone of the user
* @param a string indicate the new phone of the user
*/
void setPhone(const std::string &t_phone);
private:
std::string m_name;
std::string m_password;
std::string m_email;
std::string m_phone;
};
#endif
//User.cpp
#include"User.hpp"
//#include"Date.hpp"
#include<iostream>
#include<string>
using namespace std;
User::User(const string& t_name , const string& t_pass , const string& t_e, const string& t_p )
{
m_name = t_name;
m_password = t_pass;
m_email = t_e;
m_phone = t_p;
}
User::User(const User& other)
{
m_name = other.m_name;
m_password = other.m_password;
m_email = other.m_email;
m_phone = other.m_phone;
}
string User::getName() const
{
return m_name;
}
void User::setName(const string& str)
{
m_name = str;
}
string User::getPassword() const
{
return m_password;
}
void User::setPassword(const string& str)
{
m_password = str;
}
string User::getEmail() const
{
return m_email;
}
void User::setEmail(const string& str)
{
m_email = str;
}
string User::getPhone() const
{
return m_phone;
}
void User::setPhone(const string& str)
{
m_phone = str;
}
//Meeting.hpp
#ifndef MEETING_H
#define MEETING_H
#include <vector>
#include "Date.hpp"
class Meeting {
public:
/**
* @brief default constructor
*/
Meeting() = default;
/**
* @brief constructor with argument
*/
Meeting(const std::string &t_sponsor,
const std::vector<std::string> &t_participator,
const Date &t_startTime, const Date &t_endTime,
const std::string &t_title);
/**
* @brief copy constructor of left value
*/
Meeting(const Meeting &t_meeting);
/**
* @brief get the meeting's sponsor
* @return a string indicate sponsor
*/
std::string getSponsor(void) const;
/**
* @brief set the sponsor of a meeting
* @param the new sponsor string
*/
void setSponsor(const std::string &t_sponsor);
/**
* @brief get the participators of a meeting
* @return return a string vector indicate participators
*/
std::vector<std::string> getParticipator(void) const;
/**
* @brief set the new participators of a meeting
* @param the new participators vector
*/
void setParticipator(const std::vector<std::string> &t_participators);
/**
* @brief add a new participator to the meeting
* @param the new participator
*/
void addParticipator(const std::string &t_participator);
/**
* @brief remove a participator of the meeting
* @param the participator to be removed
*/
void removeParticipator(const std::string &t_participator);
/**
* @brief get the startDate of a meeting
* @return return a string indicate startDate
*/
Date getStartDate(void) const;
/**
* @brief set the startDate of a meeting
* @param the new startdate of a meeting
*/
void setStartDate(const Date &t_startTime);
/**
* @brief get the endDate of a meeting
* @return a date indicate the endDate
*/
Date getEndDate(void) const;
/**
* @brief set the endDate of a meeting
* @param the new enddate of a meeting
*/
void setEndDate(const Date &t_endTime);
/**
* @brief get the title of a meeting
* @return a date title the endDate
*/
std::string getTitle(void) const;
/**
* @brief set the title of a meeting
* @param the new title of a meeting
*/
void setTitle(const std::string &t_title);
/**
* @brief check if the user take part in this meeting
* @param t_username the source username
* @return if the user take part in this meeting
*/
bool isParticipator(const std::string &t_username) const;
private:
std::string m_sponsor;
std::vector<std::string> m_participators;
Date m_startDate;
Date m_endDate;
std::string m_title;
};
#endif
//Meeting.cpp
#include"Meeting.hpp"
#include<iostream>
#include<string>
#include<vector>
using namespace std;
Meeting::Meeting(const string& t_sp , const vector<string>& t_p ,const Date& t_st, const Date& t_e, const string& t_t)
{
m_sponsor = t_sp;
int len = t_p.size();
for(int index = 0 ; index < len ; index++)
m_participators.push_back(t_p[index]);
m_startDate = t_st;
m_endDate = t_e;
m_title = t_t;
}
Meeting::Meeting(const Meeting& t_m)
{
m_sponsor = t_m.m_sponsor;
int len = t_m.m_participators.size();
for(int index = 0 ; index < len ; index++)
m_participators.push_back(t_m.m_participators[index]);
m_startDate = t_m.m_startDate;
m_endDate = t_m.m_endDate;
m_title = t_m.m_title;
}
string Meeting::getSponsor(void) const
{
return m_sponsor;
}
void Meeting::setSponsor(const string& str)
{
m_sponsor = str;
}
vector<string> Meeting::getParticipator(void) const
{
// vector<string> str;
//int len = m_participators.size();
//for(int index = 0 ; index < len ; index++)
// str.push_back(m_participators[index]);
//return str;
return m_participators;
}
void Meeting::setParticipator(const std::vector<std::string> &t_pa)
{
m_participators.clear();
int len = t_pa.size();
for(int index = 0 ; index < len ; index++)
m_participators.push_back(t_pa[index]);
}
void Meeting::addParticipator(const string& str)
{
m_participators.push_back(str);
}
void Meeting::removeParticipator(const string& str)
{
vector<string>::iterator it, itor;
for(it = m_participators.begin() ; it != m_participators.end();)
{
if(*it == str)
{
itor = it;
it = m_participators.erase(itor);
}
else
it++;
}
}
Date Meeting::getStartDate(void) const
{
return m_startDate;
}
void Meeting::setStartDate(const Date& str)
{
m_startDate = str;
}
Date Meeting::getEndDate(void) const
{
return m_endDate;
}
void Meeting::setEndDate(const Date& str)
{
m_endDate = str;
}
string Meeting::getTitle(void) const
{
return m_title;
}
void Meeting::setTitle(const string& str)
{
m_title = str;
}
bool Meeting::isParticipator(const string& str) const
{
int len = m_participators.size();
for(int index = 0 ; index < len ; index++)
{
if(m_participators[index] == str)
return true;
}
return false;
}
//Storage.hpp
#ifndef AGENDA_STORAGE_H
#define AGENDA_STORAGE_H
#include <functional>
#include <list>
#include <memory>
#include <string>
#include "Meeting.hpp"
#include "User.hpp"
class Storage {
private:
/**
* default constructor
*/
Storage();
/**
* disallow the copy constructor and assign operator
*/
Storage(const Storage &t_another) = delete;
void operator=(const Storage &t_another) = delete;
/**
* read file content into memory
* @return if success, true will be returned
*/
bool readFromFile(void);
/**
* write file content from memory
* @return if success, true will be returned
*/
bool writeToFile(void);
public:
/**
* get Instance of storage
* @return the pointer of the instance
*/
static std::shared_ptr<Storage> getInstance(void);
/**
* destructor
*/
~Storage();
// CRUD for User & Meeting
// using C++11 Function Template and Lambda Expressions
/**
* create a user
* @param a user object
*/
void createUser(const User &t_user);
/**
* query users
* @param a lambda function as the filter
* @return a list of fitted users
*/
std::list<User> queryUser(std::function<bool(const User &)> filter) const;
/**
* update users
* @param a lambda function as the filter
* @param a lambda function as the method to update the user
* @return the number of updated users
*/
int updateUser(std::function<bool(const User &)> filter,
std::function<void(User &)> switcher);
/**
* delete users
* @param a lambda function as the filter
* @return the number of deleted users
*/
int deleteUser(std::function<bool(const User &)> filter);
/**
* create a meeting
* @param a meeting object
*/
void createMeeting(const Meeting &t_meeting);
/**
* query meetings
* @param a lambda function as the filter
* @return a list of fitted meetings
*/
std::list<Meeting> queryMeeting(
std::function<bool(const Meeting &)> filter) const;
/**
* update meetings
* @param a lambda function as the filter
* @param a lambda function as the method to update the meeting
* @return the number of updated meetings
*/
int updateMeeting(std::function<bool(const Meeting &)> filter,
std::function<void(Meeting &)> switcher);
/**
* delete meetings
* @param a lambda function as the filter
* @return the number of deleted meetings
*/
int deleteMeeting(std::function<bool(const Meeting &)> filter);
/**
* sync with the file
*/
bool sync(void);
private:
static std::shared_ptr<Storage> m_instance;
std::list<User> m_userList;
std::list<Meeting> m_meetingList;
bool m_dirty;
};
#endif
//Storage.cpp
#include"Path.hpp"
#include"User.hpp"
#include"Meeting.hpp"
#include"Date.hpp"
#include"Storage.hpp"
#include<functional>
#include<string>
#include<iostream>
#include<list>
#include<fstream>
#include<memory>
#include<vector>
#include<functional>
using namespace std;
#define SIGNAL1
#define P
shared_ptr<Storage> Storage::m_instance = nullptr;
//int
Storage::Storage()
{
// if(m_instance == nullptr)
// m_instance(new Storage);
m_dirty = false;
readFromFile();
}
bool Storage::readFromFile(void)
{
ifstream fout(Path::meetingPath);
ifstream foutu(Path::userPath);
if(fout.is_open() == false)
{
// cout<<"wrong"<<endl;
return false;}
if(foutu.is_open() == false)
{
// cout<<"wrong"<<endl;
return false;}
string name;
string pass;
string mail;
string phone;
char ch;
// int dc = 0;
//while(!foutu.eof())
while(1)
{
/* foutu>>ch;
getline(foutu,name,'"');
foutu>>ch;
foutu>>ch;
getline(foutu,pass,'"');
foutu>>ch;
foutu>>ch;
getline(foutu,mail,'"');
foutu>>ch;
foutu>>ch;
getline(foutu,phone,'"');
foutu>>ch;
if(!foutu.eof())
foutu>>ch;
User u(name,pass,mail,phone);
m_userList.push_back(u);
//cout<<dc++<<endl;
*/
string str;
getline(foutu,str);
//cout<<str<<endl;
vector<int> sign;
int len = str.size();
for(int index = 0; index < len ; index++)
{
if(str[index] == '"')
sign.push_back(index);
}
if(sign.size() != 8)
break;
string name;
string pass;
string email;
string phone;
for(int index = sign[0]+1 ; index < sign[1] ; index++)
name.push_back(str[index]);
for(int index = sign[2]+1 ; index < sign[3] ; index++)
pass.push_back(str[index]);
for(int index = sign[4]+1 ; index < sign[5] ; index++)
email.push_back(str[index]);
for(int index = sign[6]+1 ; index < sign[7] ; index++)
phone.push_back(str[index]);
User u(name,pass,email,phone);
m_userList.push_back(u);
}
//cout<<"break"<<endl;
foutu.close();
string spon;
string temp_v;
vector<string> v;
string start;
string end;
string title;
//while(!fout.eof())
while(1)
{
/*fout>>ch;
getline(fout,spon,'"');
foutu>>ch;
foutu>>ch;
getline(fout,temp_v,'"');
foutu>>ch;
foutu>>ch;
getline(fout,start,'"');
foutu>>ch;
foutu>>ch;
getline(fout,end,'"');
foutu>>ch;
foutu>>ch;
getline(fout,title,'"');
vector<int> data;
int len = temp_v.size();
for(int index = 0 ; index < len ; index++ )
if(temp_v[index] == '&')
data.push_back(index);
int leng = data.size()+1;
for(int index = 0 ; index < leng ; index++ )
{
if(index == 0)
{
string str;
for(int jndex = 0 ;jndex <= temp_v[index]-1; jndex++)
str.push_back(temp_v[jndex]);
v.push_back(str);
continue;
}
if(index == leng - 1)
{ string str;
for(int jndex = data[leng-2]+1 ; jndex < len ; jndex++)
str.push_back(temp_v[jndex]);
v.push_back(str);
continue;
}
string str;
for(int jndex = data[index-1]+1 ; jndex < data[index]; jndex++)
str.push_back(temp_v[jndex]);
v.push_back(str);
}
Date s(start), e(end);
Meeting m(spon,v,s,e,title);
m_meetingList.push_back(m);
if(!fout.eof())
fout>>ch;
*/
vector<int> sign;
vector<int> sep;
//vector<int> par;
string str;
getline(fout,str);
//cout<<str<<endl;
vector<string> par;
string spon;
string startDate;
string endDate;
string title;
int len = str.size();
if(len<=2) break;
//if(sign.size() != 10)
//break;
for(int index = 0 ; index < len ; index++)
{
if(str[index] == '"')
sign.push_back(index);
if(str[index] == '&')
sep.push_back(index);
}
if(sign.size() < 2)
break;
for(int index = sign[0]+1 ; index < sign[1] ; index++)
spon.push_back(str[index]);
for(int index = sign[4]+1 ; index < sign[5] ; index++)
startDate.push_back(str[index]);
for(int index = sign[6]+1 ; index < sign[7] ; index++)