add csci-1200-hw-2

This commit is contained in:
JamesFlare1212
2025-01-31 13:20:17 -05:00
parent a10a010701
commit 6726a156b3
10 changed files with 2137 additions and 13 deletions

View File

@@ -120,8 +120,6 @@ Good morning <proper name>!
{{< link href="HW1.zip" content="HW1.zip" title="下载 HW1.zip" download="HW1.zip" card=true >}}
***
## 参考答案
### hw1_part1.py

View File

@@ -182,8 +182,6 @@ repost:
{{< link href="HW2.zip" content="HW2.zip" title="下载 HW2.zip" download="HW2.zip" card=true >}}
***
## 参考答案
### hw2_part1.py

View File

@@ -10,7 +10,7 @@ author:
link: https://www.jamesflare.com
email:
avatar: /site-logo.avif
description:
description: 这篇博客文章详细介绍了如何在C++中实现一个简单的拼车应用程序作为CSCI-1200课程作业的一部分。该实现涉及使用向量存储数据来处理乘客请求和司机取消操作并遵循特定的输入和输出文件格式。
keywords: ["C++", "编程", "作业", "String", "Vector", "Class"]
license:
comment: true
@@ -29,7 +29,7 @@ hiddenFromHomePage: false
hiddenFromSearch: false
hiddenFromRss: false
hiddenFromRelated: false
summary:
summary: 这篇博客文章详细介绍了如何在C++中实现一个简单的拼车应用程序作为CSCI-1200课程作业的一部分。该实现涉及使用向量存储数据来处理乘客请求和司机取消操作并遵循特定的输入和输出文件格式。
resources:
- name: featured-image
src: featured-image.jpg
@@ -396,6 +396,10 @@ A: 与 Uber 相同。保留一位小数。直接截断即可。例如,如果
- 成员变量是公开的。 (-2)
````
## 支持文件
{{< link href="ride_sharing.7z" content="ride_sharing.7z" title="Download ride_sharing.7z" download="ride_sharing.7z" card=true >}}
## 程序设计
由于这次作业比较复杂我们在开始前最好好好构思一下怎么实现。这里我借用两种情况也就是指令是“request”和“cancel”两种情况分别设计它们单独的流程然后在主程序中使用这两部分。姑且把它们称作`handleRequest()`以及`handleCancel()`。
@@ -461,3 +465,829 @@ flowchart TD
```
有了流程图我们就可以慢慢实现它们了。当然,不一定要真写`handleRequest()`和`handleCancel()`两个function。把它们的逻辑直接在`main()`中实现也是可以的,我这里只是为了思路清晰而已。
此外我们要设计两个Class因为这是作业要求也是为了方便我们实现功能。
```mermaid
classDiagram
class Rider {
%% 数据成员
- firstName :
- lastName : string
- gender : string
- age : int
- phoneNumber : string
- rating : double
- pickupLocationName : string
- pickupLatitude : double
- pickupLongitude : double
- dropoffLocationName : string
- dropoffLatitude : double
- dropoffLongitude : double
- vehiclePref : string
- currentState : string
- driverFirstName : string
- driverLastName : string
- driverPhoneNumber : string
%% 构造函数
+ Rider()
%% 方法
+ getFirstName()
+ getLastName()
+ getGender()
+ getAge()
+ getPhoneNumber()
+ getRating()
+ getPickupLocationName()
+ getPickupLatitude()
+ getPickupLongitude()
+ getDropoffLocationName()
+ getDropoffLatitude()
+ getDropoffLongitude()
+ getVehiclePref()
+ getCurrentState()
+ getDriverFirstName()
+ getDriverLastName()
+ getDriverPhoneNumber()
+ setCurrentState()
+ setDriverInfo()
+ toFileString()
}
class Driver {
%% 数据成员
- firstName : string
- lastName : string
- gender : string
- age : int
- phoneNumber : string
- rating : double
- latitude : double
- longitude : double
- vehicleType : string
- currentState : string
- riderFirstName : string
- riderLastName : string
- riderPhoneNumber : string
%% 构造函数
+ Driver()
%% 方法
+ getFirstName()
+ getLastName()
+ getGender()
+ getAge()
+ getPhoneNumber()
+ getRating()
+ getLatitude()
+ getLongitude()
+ getVehicleType()
+ getCurrentState()
+ getRiderFirstName()
+ getRiderLastName()
+ getRiderPhoneNumber()
+ setCurrentState()
+ setRiderInfo()
+ toFileString()
}
```
## 踩坑内容
1. 在打印`output0.txt`时looking for 后面要跟一个 Rider 期望的vehicle。但是这个vehicle可能有元音字母所以要判断一下到底是用a还是an。这是一个小问题实现起来并不复杂但是别忘了。我用了一个function来返回a还是an。
```cpp
std::string autoAAn(const std::string &word) {
if (word.empty()) return "";
if (word[0] == 'A' || word[0] == 'E' || word[0] == 'I' || word[0] == 'O' || word[0] == 'U') {
return "an";
}
return "a";
}
```
然后在后面配合`<sstream>`的`ostringstream`的方式拼接从Rider Class获取的字段。下面的代码就展示以下逻辑和结构不必较真。
```cpp
#include <sstream>
//...
Rider &r = riders[rIdx]; //just consider `r` as your rider class
std::ostringstream msg;
msg << "Ride requested for rider " << r.getFirstName()
<< ", looking for " << autoAAn(r.getVehiclePref()) << " "
<< r.getVehiclePref() << " vehicle.\n"
<< "Pick Up Location: " << r.getPickupLocationName()
<< ", Drop Off Location: " << r.getDropoffLocationName() << ".\n";
```
2. 在处理司机状态的时候要特别小心,一旦有变化要马上更新,因为一些逻辑是依赖于司机状态的。比如当司机从`On_the_way_to_pickup`变为`Available`时需要清空Rider关联信息并且再自动为Rider找新司机。重新寻找司机的时候也要避免重新找到之前已经分配过的司机。
3. Class的变量不能是Public作业要求调用内容必须用方法而不是直接对变量操作。
4. 根据作业要求,我们不能用`auto`类型这导致我不得不修改了for循环的内容比如
```diff
void exportDrivers(const std::string &filename, const std::vector<Driver> &drivers) {
//...
std::ofstream ofs(filename);
- for (const auto &d : drivers) {
+ for (int i = 0; i < (int)drivers.size(); i++) {
+ const Driver &d = drivers[i];
ofs << d.toFileString() << "\n";
}
ofs.close();
}
```
## 参考代码
### nyrider.cpp
```cpp
//An implement of CSCI-1200 HW2 Ride Sharing
//Author: JamesFlare
//Date: 2025/1/20
//#include <algorithm>
//#include <cstdlib>
#include <cmath>
#include <vector>
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
#include <iomanip>
#include "Driver.h"
#include "Rider.h"
void debug_print(const std::string &msg) {
std::cout << "DEBUG: " << msg << std::endl;
}
bool isPhoneNumberValid(const std::string &phone)
{
if (phone.size() != 12) return false;
//xxx-xxx-xxxx
for (int i = 0; i < 12; i++) {
if (i == 3 || i == 7) {
if (phone[i] != '-') return false;
} else {
if (!std::isdigit((unsigned char)phone[i])) return false;
}
}
return true;
}
void loadDrivers(std::ifstream &ifs, std::vector<Driver> &drivers) {
//read the file line by line, total of 13
while (!ifs.eof()) {
std::string fName, lName, gender, phone, vehicleType, state;
std::string rF, rL, rP;
int age;
double rating, lat, lon;
ifs >> fName >> lName >> gender >> age >> phone >> rating >> lat >> lon
>> vehicleType >> state >> rF >> rL >> rP;
if (!ifs.fail()) {
//change "null" to empty string
if (rF == "null") rF = "";
if (rL == "null") rL = "";
if (rP == "null") rP = "";
//create driver
Driver d(fName, lName, gender, age, phone, rating, lat, lon,
vehicleType, state, rF, rL, rP);
drivers.push_back(d);
}
}
ifs.close();
}
void loadRiders(std::ifstream &ifs, std::vector<Rider> &riders) {
//read the file line by line, total of 17
while (!ifs.eof()) {
std::string fName, lName, gender, phone, pickupLoc, dropoffLoc, vPref, state;
std::string dF, dL, dP;
int age;
double rating, pickupLat, pickupLon, dropoffLat, dropoffLon;
ifs >> fName >> lName >> gender >> age >> phone >> rating
>> pickupLoc >> pickupLat >> pickupLon
>> dropoffLoc >> dropoffLat >> dropoffLon
>> vPref >> state
>> dF >> dL >> dP;
if (!ifs.fail()) {
//fill null with empty string
if (dF == "null") dF = "";
if (dL == "null") dL = "";
if (dP == "null") dP = "";
//create rider
Rider r(fName, lName, gender, age, phone, rating,
pickupLoc, pickupLat, pickupLon,
dropoffLoc, dropoffLat, dropoffLon,
vPref, state, dF, dL, dP);
riders.push_back(r);
}
}
ifs.close();
}
std::ifstream loadFile(const std::string &filename) {
//read file and return ifstream
std::ifstream ifs(filename);
if (!ifs) {
std::cerr << "Error opening file: " << filename << std::endl;
exit(1);
}
return ifs;
}
void saveFile(const std::string &filename, const std::string &msg) {
std::ofstream ofs(filename);
if (!ofs) {
std::cerr << "Error opening file: " << filename << std::endl;
exit(1);
}
ofs << msg;
ofs.close();
}
void exportDrivers(const std::string &filename, const std::vector<Driver> &drivers) {
//save drivers to file
std::ofstream ofs(filename);
if (!ofs) {
std::cerr << "Error opening output file: " << filename << std::endl;
return;
}
for (int i = 0; i < (int)drivers.size(); i++) {
const Driver &d = drivers[i];
ofs << d.toFileString() << "\n";
}
ofs.close();
}
void exportRiders(const std::string &filename, const std::vector<Rider> &riders) {
//save riders to file
std::ofstream ofs(filename);
if (!ofs) {
std::cerr << "Error opening output file: " << filename << std::endl;
return;
}
for (int i = 0; i < (int)riders.size(); i++) {
const Rider &r = riders[i];
ofs << r.toFileString() << "\n";
}
ofs.close();
}
// calculate the distance between two coordinates using Haversine formula
double calculateDistance(double lat1, double lon1, double lat2, double lon2) {
const double radiusOfEarth = 6371.0; // Earth's radius in kilometers
// convert latitude and longitude from degrees to radians
lat1 *= M_PI / 180.0;
lon1 *= M_PI / 180.0;
lat2 *= M_PI / 180.0;
lon2 *= M_PI / 180.0;
// Haversine formula
double dLat = lat2 - lat1;
double dLon = lon2 - lon1;
double a = sin(dLat / 2.0) * sin(dLat / 2.0) + cos(lat1) * cos(lat2) * sin(dLon / 2.0) * sin(dLon / 2.0);
double c = 2.0 * atan2(sqrt(a), sqrt(1.0 - a));
// distance in kilometers
double distanceKM = radiusOfEarth * c;
// convert it to distance in miles
double distanceMiles = distanceKM * 0.621371;
return distanceMiles;
}
int findClosestDriver(const std::vector<Driver> &drivers,
const Rider &rider) {
double minDistance = 1e9;
int bestIndex = -1;
for (int i = 0; i < (int)drivers.size(); i++) {
const Driver &drv = drivers[i];
if (drv.getCurrentState() == "Available" &&
drv.getVehicleType() == rider.getVehiclePref()) {
double dist = calculateDistance(drv.getLatitude(), drv.getLongitude(),
rider.getPickupLatitude(), rider.getPickupLongitude());
if (dist < minDistance) {
minDistance = dist;
bestIndex = i;
}
}
}
return bestIndex;
}
int findRiderIndexByPhone(const std::vector<Rider> &riders, const std::string &phone) {
for (int i = 0; i < (int)riders.size(); i++) {
if (riders[i].getPhoneNumber() == phone) {
return i;
}
}
return -1;
}
int findDriverIndexByPhone(const std::vector<Driver> &drivers, const std::string &phone) {
for (int i = 0; i < (int)drivers.size(); i++) {
if (drivers[i].getPhoneNumber() == phone) {
return i;
}
}
return -1;
}
std::string autoAAn(const std::string &word) {
if (word.empty()) return "";
if (word[0] == 'A' || word[0] == 'E' || word[0] == 'I' || word[0] == 'O' || word[0] == 'U') {
return "an";
}
return "a";
}
int main(int argc, char *argv[]) {
//take 3 arguments
if (argc < 8) {
std::cout << "Usage: nyride drivers.txt riders.txt output0.txt output1.txt output2.txt phoneNumber [request|cancel]\n" << std::endl;
return 1;
}
//load arguments
const std::string drivers_fName = argv[1];
const std::string riders_fName = argv[2];
std::string msg_fName = argv[3];
std::string updated_drivers_fName = argv[4];
std::string updated_riders_fName = argv[5];
std::string phone_number = argv[6];
std::string command = argv[7];
//turn on debug mode is last argument is debug
bool debug_mode = false;
if (std::string(argv[argc - 1]) == "debug") {
debug_mode = true;
}
if (debug_mode) {
debug_print("drivers_fName = " + drivers_fName);
debug_print("riders_fName = " + riders_fName);
debug_print("msg_fName = " + msg_fName);
debug_print("updated_drivers_fName = " + updated_drivers_fName);
debug_print("updated_riders_fName = " + updated_riders_fName);
debug_print("phone_number = " + phone_number);
debug_print("command = " + command);
}
//load drivers
std::vector<Driver> drivers;
std::ifstream drivers_file = loadFile(drivers_fName);
loadDrivers(drivers_file, drivers);
//load riders
std::vector<Rider> riders;
std::ifstream riders_file = loadFile(riders_fName);
loadRiders(riders_file, riders);
if (debug_mode) {
debug_print("drivers.size() = " + std::to_string(drivers.size()));
debug_print("riders.size() = " + std::to_string(riders.size()));
}
//check if phone number is valid
std::ostringstream msg;
if (!isPhoneNumberValid(phone_number)) {
std::cout << "Error: Invalid phone number" << std::endl;
msg << "Phone number is invalid.\n";
saveFile(msg_fName, msg.str());
return 1;
}
//check if command is valid
if (command != "request" && command != "cancel") {
std::cout << "Error: Invalid command" << std::endl;
return 1;
} else if (command == "request") {
//for request cases
int rIdx = findRiderIndexByPhone(riders, phone_number);
if (rIdx == -1) {
//if rider does not exist
msg << "Account does not exist.\n";
saveFile(msg_fName, msg.str());
return 1;
}
Rider &r = riders[rIdx];
//check rider
if (r.getCurrentState() == "Driver_on_the_way") {
msg << "You have already requested a ride and your driver is on the way to the pickup location.\n";
saveFile(msg_fName, msg.str());
return 1;
}
if (r.getCurrentState() == "During_the_trip") {
msg << "You can not request a ride at this moment as you are already on a trip.\n";
saveFile(msg_fName, msg.str());
return 1;
}
if (r.getCurrentState() == "Ready_to_request") {
msg << "Ride requested for rider " << r.getFirstName()
<< ", looking for " << autoAAn(r.getVehiclePref()) << " "
<< r.getVehiclePref() << " vehicle.\n"
<< "Pick Up Location: " << r.getPickupLocationName()
<< ", Drop Off Location: " << r.getDropoffLocationName() << ".\n";
//find closest driver
int dIdx = findClosestDriver(drivers, r);
if (dIdx == -1) {
//no driver
msg << "Sorry we can not find a driver for you at this moment.\n";
} else {
Driver &d = drivers[dIdx];
double dist = calculateDistance(d.getLatitude(), d.getLongitude(),
r.getPickupLatitude(), r.getPickupLongitude());
dist = (int)(dist * 10) / 10.0; //cut to 1 decimal
msg << "We have found the closest driver " << d.getFirstName() << "("
<< std::fixed << std::setprecision(1) << d.getRating() << ") for you.\n"
<< d.getFirstName() << " is now "
<< std::fixed << std::setprecision(1) << dist
<< " miles away from you.\n";
//update status
d.setCurrentState("On_the_way_to_pickup");
d.setRiderInfo(r.getFirstName(), r.getLastName(), r.getPhoneNumber());
r.setCurrentState("Driver_on_the_way");
r.setDriverInfo(d.getFirstName(), d.getLastName(), d.getPhoneNumber());
}
}
} else if (command == "cancel") {
//for cancel cases
//find phone_number in riders
int rIdx = findRiderIndexByPhone(riders, phone_number);
if (rIdx == -1) {
//in case of driver's cancel
int dIdx = findDriverIndexByPhone(drivers, phone_number);
if (dIdx == -1) {
//in case of not both rider and driver
msg << "Account does not exist.\n";
saveFile(msg_fName, msg.str());
return 1;
}
Driver &driver = drivers[dIdx];
if (driver.getCurrentState() != "On_the_way_to_pickup") {
msg << "You can only cancel a ride request if you are currently on the way to the pickup location.\n";
saveFile(msg_fName, msg.str());
return 1;
}
//get rider's phone number
std::string rPh = driver.getRiderPhoneNumber();
//clean driver's rider info
driver.setCurrentState("Available");
driver.setRiderInfo("", "", "");
msg << "Your driver " << driver.getFirstName()
<< " has canceled the ride request. We will now find a new driver for you.\n";
//find rider
int theRiderIdx = findRiderIndexByPhone(riders, rPh);
Rider &r = riders[theRiderIdx];
//reset rider
r.setCurrentState("Ready_to_request");
r.setDriverInfo("", "", "");
//find a new driver
msg << "Ride requested for rider " << r.getFirstName()
<< ", looking for " << autoAAn(r.getVehiclePref()) << " "
<< r.getVehiclePref() << " vehicle.\n"
<< "Pick Up Location: " << r.getPickupLocationName()
<< ", Drop Off Location: " << r.getDropoffLocationName() << ".\n";
int newDIdx = findClosestDriver(drivers, r);
if (newDIdx == -1) {
msg << "Sorry we can not find a driver for you at this moment.\n";
} else {
Driver &newDriver = drivers[newDIdx];
double dist = calculateDistance(newDriver.getLatitude(), newDriver.getLongitude(),
r.getPickupLatitude(), r.getPickupLongitude());
dist = (int)(dist * 10) / 10.0; //cut to 1 decimal
msg << "We have found the closest driver " << newDriver.getFirstName() << "("
<< std::fixed << std::setprecision(1) << newDriver.getRating() << ") for you.\n"
<< newDriver.getFirstName() << " is now "
<< std::fixed << std::setprecision(1) << dist
<< " miles away from you.\n";
//update driver's status
newDriver.setCurrentState("On_the_way_to_pickup");
newDriver.setRiderInfo(r.getFirstName(), r.getLastName(), r.getPhoneNumber());
//update rider's status
r.setCurrentState("Driver_on_the_way");
r.setDriverInfo(newDriver.getFirstName(), newDriver.getLastName(), newDriver.getPhoneNumber());
}
} else {
//in case of rider's cancel
Rider &rider = riders[rIdx];
if (rider.getCurrentState() != "Driver_on_the_way") {
msg << "You can only cancel a ride request if your driver is currently on the way to the pickup location.\n";
saveFile(msg_fName, msg.str());
return 1;
}
//find driver's phone_number
std::string dPh = rider.getDriverPhoneNumber();
msg << "Ride request for rider " << rider.getFirstName()
<< " is now canceled by the rider.\n";
//set driver's status to Available
int dIdx = findDriverIndexByPhone(drivers, dPh);
if (dIdx != -1) {
Driver &drv = drivers[dIdx];
drv.setCurrentState("Available");
drv.setRiderInfo("", "", "");
}
//set rider's status to Ready_to_request
rider.setCurrentState("Ready_to_request");
rider.setDriverInfo("", "", "");
}
}
//save msg
saveFile(msg_fName, msg.str());
//save updated drivers and riders
exportDrivers(updated_drivers_fName, drivers);
exportRiders(updated_riders_fName, riders);
return 0;
}
```
### Rider.h
```cpp
#ifndef __RIDER_H
#define __RIDER_H
#include <string>
class Rider {
private:
std::string firstName;
std::string lastName;
std::string gender;
int age;
std::string phoneNumber;
double rating;
std::string pickupLocationName;
double pickupLatitude;
double pickupLongitude;
std::string dropoffLocationName;
double dropoffLatitude;
double dropoffLongitude;
std::string vehiclePref;
std::string currentState;
//driver's info
std::string driverFirstName;
std::string driverLastName;
std::string driverPhoneNumber;
public:
//init
Rider();
Rider(const std::string &fName, const std::string &lName,
const std::string &gen, int a, const std::string &phone,
double r, const std::string &pickupLocName, double pickupLat, double pickupLon,
const std::string &dropoffLocName, double dropoffLat, double dropoffLon,
const std::string &vehiclePref, const std::string &state,
const std::string &dF, const std::string &dL, const std::string &dP);
//getters & setters
const std::string& getFirstName() const;
const std::string& getLastName() const;
const std::string& getGender() const;
int getAge() const;
const std::string& getPhoneNumber() const;
double getRating() const;
const std::string& getPickupLocationName() const;
double getPickupLatitude() const;
double getPickupLongitude() const;
const std::string& getDropoffLocationName() const;
double getDropoffLatitude() const;
double getDropoffLongitude() const;
const std::string& getVehiclePref() const;
const std::string& getCurrentState() const;
const std::string& getDriverFirstName() const;
const std::string& getDriverLastName() const;
const std::string& getDriverPhoneNumber() const;
void setCurrentState(const std::string &state);
void setDriverInfo(const std::string &df, const std::string &dl, const std::string &dp);
//return a string representation of the rider
std::string toFileString() const;
};
#endif
```
### Rider.cpp
```cpp
#include "Rider.h"
#include <sstream>
Rider::Rider()
: age(0), rating(0.0), pickupLatitude(0.0), pickupLongitude(0.0),
dropoffLatitude(0.0), dropoffLongitude(0.0) {}
Rider::Rider(const std::string &fName, const std::string &lName,
const std::string &gen, int a, const std::string &phone,
double r, const std::string &pickupLocName, double pickupLat, double pickupLon,
const std::string &dropoffLocName, double dropoffLat, double dropoffLon,
const std::string &vPref, const std::string &state,
const std::string &dF, const std::string &dL, const std::string &dP)
: firstName(fName), lastName(lName), gender(gen), age(a),
phoneNumber(phone), rating(r),
pickupLocationName(pickupLocName), pickupLatitude(pickupLat), pickupLongitude(pickupLon),
dropoffLocationName(dropoffLocName), dropoffLatitude(dropoffLat), dropoffLongitude(dropoffLon),
vehiclePref(vPref), currentState(state),
driverFirstName(dF), driverLastName(dL), driverPhoneNumber(dP) {}
const std::string& Rider::getFirstName() const { return firstName; }
const std::string& Rider::getLastName() const { return lastName; }
const std::string& Rider::getGender() const { return gender; }
int Rider::getAge() const { return age; }
const std::string& Rider::getPhoneNumber() const { return phoneNumber; }
double Rider::getRating() const { return rating; }
const std::string& Rider::getPickupLocationName() const { return pickupLocationName; }
double Rider::getPickupLatitude() const { return pickupLatitude; }
double Rider::getPickupLongitude() const { return pickupLongitude; }
const std::string& Rider::getDropoffLocationName() const { return dropoffLocationName; }
double Rider::getDropoffLatitude() const { return dropoffLatitude; }
double Rider::getDropoffLongitude() const { return dropoffLongitude; }
const std::string& Rider::getVehiclePref() const { return vehiclePref; }
const std::string& Rider::getCurrentState() const { return currentState; }
const std::string& Rider::getDriverFirstName() const { return driverFirstName; }
const std::string& Rider::getDriverLastName() const { return driverLastName; }
const std::string& Rider::getDriverPhoneNumber() const { return driverPhoneNumber; }
void Rider::setCurrentState(const std::string &state) {
currentState = state;
}
void Rider::setDriverInfo(const std::string &df, const std::string &dl, const std::string &dp) {
driverFirstName = df;
driverLastName = dl;
driverPhoneNumber = dp;
}
std::string Rider::toFileString() const {
//Isabella
//Richard
//Female
//39
//301-144-6533
//3.2
//Top_of_the_Rock
//40.7593 -73.979
//Gowanus
//40.6733
//-73.99
//Economy
//Ready_to_request
//null
//null
//null
std::ostringstream oss;
oss << firstName << " "
<< lastName << " "
<< gender << " "
<< age << " "
<< phoneNumber << " "
<< rating << " "
<< pickupLocationName << " "
<< pickupLatitude << " "
<< pickupLongitude << " "
<< dropoffLocationName << " "
<< dropoffLatitude << " "
<< dropoffLongitude << " "
<< vehiclePref << " "
<< currentState << " "
<< (driverFirstName.empty() ? "null" : driverFirstName) << " "
<< (driverLastName.empty() ? "null" : driverLastName) << " "
<< (driverPhoneNumber.empty() ? "null" : driverPhoneNumber);
return oss.str();
}
```
### Driver.h
```cpp
#ifndef __DRIVER_H
#define __DRIVER_H
#include <string>
class Driver {
private:
std::string firstName;
std::string lastName;
std::string gender;
int age;
std::string phoneNumber;
double rating;
double latitude;
double longitude;
std::string vehicleType;
std::string currentState;
//rider's info
std::string riderFirstName;
std::string riderLastName;
std::string riderPhoneNumber;
public:
//init
Driver();
Driver(const std::string &firstName, const std::string &lastName,
const std::string &gender, int age, const std::string &phoneNumber,
double rating, double latitude, double longitude,
const std::string &vehicleType, const std::string &currentState,
const std::string &riderFirstName, const std::string &riderLastName,
const std::string &riderPhoneNumber);
//getters & setters
const std::string& getFirstName() const;
const std::string& getLastName() const;
const std::string& getGender() const;
int getAge() const;
const std::string& getPhoneNumber() const;
double getRating() const;
double getLatitude() const;
double getLongitude() const;
const std::string& getVehicleType() const;
const std::string& getCurrentState() const;
const std::string& getRiderFirstName() const;
const std::string& getRiderLastName() const;
const std::string& getRiderPhoneNumber() const;
void setCurrentState(const std::string &state);
void setRiderInfo(const std::string &rf, const std::string &rl, const std::string &rp);
//return a string representation of the driver
std::string toFileString() const;
};
#endif
```
### Driver.cpp
```cpp
#include "Driver.h"
#include <sstream>
Driver::Driver() : age(0), rating(0.0), latitude(0.0), longitude(0.0) {}
Driver::Driver(const std::string &fName, const std::string &lName,
const std::string &gen, int a, const std::string &phone,
double r, double lat, double lon,
const std::string &vehType, const std::string &state,
const std::string &rF, const std::string &rL,
const std::string &rP)
: firstName(fName), lastName(lName), gender(gen), age(a),
phoneNumber(phone), rating(r), latitude(lat), longitude(lon),
vehicleType(vehType), currentState(state),
riderFirstName(rF), riderLastName(rL), riderPhoneNumber(rP) {}
//getters
const std::string& Driver::getFirstName() const { return firstName; }
const std::string& Driver::getLastName() const { return lastName; }
const std::string& Driver::getGender() const { return gender; }
int Driver::getAge() const { return age; }
const std::string& Driver::getPhoneNumber() const { return phoneNumber; }
double Driver::getRating() const { return rating; }
double Driver::getLatitude() const { return latitude; }
double Driver::getLongitude() const { return longitude; }
const std::string& Driver::getVehicleType() const { return vehicleType; }
const std::string& Driver::getCurrentState() const { return currentState; }
const std::string& Driver::getRiderFirstName() const { return riderFirstName; }
const std::string& Driver::getRiderLastName() const { return riderLastName; }
const std::string& Driver::getRiderPhoneNumber() const { return riderPhoneNumber; }
//setters
void Driver::setCurrentState(const std::string &state) {
currentState = state;
}
void Driver::setRiderInfo(const std::string &rf, const std::string &rl, const std::string &rp) {
riderFirstName = rf;
riderLastName = rl;
riderPhoneNumber = rp;
}
std::string Driver::toFileString() const {
//Sandra
//Huang
//Female
//25
//853-977-5304
//3.1
//40.4269
//-73.0753
//Standard
//On_the_way_to_pickup
//Michael
//Richard
//445-915-1645
std::ostringstream oss;
oss << firstName << " "
<< lastName << " "
<< gender << " "
<< age << " "
<< phoneNumber << " "
<< rating << " "
<< latitude << " "
<< longitude << " "
<< vehicleType << " "
<< currentState << " "
<< (riderFirstName.empty() ? "null" : riderFirstName) << " "
<< (riderLastName.empty() ? "null" : riderLastName) << " "
<< (riderPhoneNumber.empty() ? "null" : riderPhoneNumber);
return oss.str();
}
```

Binary file not shown.