111 lines
3.6 KiB
C++
111 lines
3.6 KiB
C++
|
// The class Patient stores the personal information of a patient as well as
|
||
|
// his/her history of medical visits as a vector of Visit objects, all as
|
||
|
// private data members. The class interface allows user code to:
|
||
|
|
||
|
// - Instantiate a Patient object given (as parameters) all his/her
|
||
|
// personal information. No visit history is required. The same
|
||
|
// function should also create a patient record file according to
|
||
|
// the format specified above.
|
||
|
|
||
|
// - Instantiate a Patient object given (as parameter) his/her ID
|
||
|
// number. The personal information as well as the visit history of
|
||
|
// the patients to be read from his existing record file.
|
||
|
|
||
|
// - Add one Visit record given a Visit object as parameter. The same
|
||
|
// function should record the Visit in the patient file.
|
||
|
|
||
|
// - Print the patient record according to the format specified in
|
||
|
// the files above using the << operator (including history)
|
||
|
|
||
|
#include "Patient.hpp"
|
||
|
#include "Visit.hpp"
|
||
|
#include <fstream>
|
||
|
#include <iostream>
|
||
|
#include <istream>
|
||
|
#include <ostream>
|
||
|
#include <sstream>
|
||
|
#include <string>
|
||
|
#include <vector>
|
||
|
|
||
|
////////////////////////////////////
|
||
|
// File: patient_files/3.txt //
|
||
|
// 3 //
|
||
|
// Amirah //
|
||
|
// Asaad //
|
||
|
// F //
|
||
|
// 26 //
|
||
|
// 3 1/1/2018 Abdullah Alshareef //
|
||
|
// 9 4/1/2018 Helen Philips //
|
||
|
// 14 8/1/2018 Abdullah Alshareef //
|
||
|
////////////////////////////////////
|
||
|
|
||
|
Patient::Patient(u_int32_t id) : id(id) {
|
||
|
auto patient_file_path = "patient_files/" + std::to_string(id) + ".txt";
|
||
|
std::ifstream patient_file{patient_file_path};
|
||
|
if (patient_file.is_open()) {
|
||
|
patient_file >> *this;
|
||
|
} else {
|
||
|
std::cerr << "Failed to read patient file at: " + patient_file_path;
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void Patient::write_patient() {
|
||
|
// create patient's file
|
||
|
// this will overwrite any patient with the same id
|
||
|
auto patient_file_path = "patient_files/" + std::to_string(id) + ".txt";
|
||
|
std::ofstream patient_file{patient_file_path};
|
||
|
if (patient_file.is_open()) {
|
||
|
patient_file << *this;
|
||
|
} else {
|
||
|
std::cerr << "Failed to create patient file at: " + patient_file_path;
|
||
|
exit(1);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
u_int32_t Patient::get_id() const { return id; }
|
||
|
|
||
|
void Patient::add_visit(Visit const &visit) {
|
||
|
visits.push_back(visit);
|
||
|
// could have logic to append data and not re-write the whole thing, but not
|
||
|
// worth it
|
||
|
// this rewrites the entire file each time a visits gets added
|
||
|
write_patient();
|
||
|
}
|
||
|
|
||
|
std::ostream &operator<<(std::ostream &out, Patient &patient) {
|
||
|
// clang-format off
|
||
|
out << patient.id << "\n";
|
||
|
out << patient.first_name << "\n"<< patient.last_name << "\n";
|
||
|
out << patient.gender_char() << "\n";
|
||
|
out << patient.age << "\n";
|
||
|
for (auto visit : patient.visits)
|
||
|
out << visit << "\n";
|
||
|
return out;
|
||
|
// clang-format on
|
||
|
}
|
||
|
std::istream &operator>>(std::istream &in, Patient &patient) {
|
||
|
char gender_char{};
|
||
|
in >> patient.id;
|
||
|
in >> patient.first_name >> patient.last_name;
|
||
|
in >> gender_char;
|
||
|
in >> patient.age;
|
||
|
|
||
|
patient.gender = gender_char == 'M' ? true : false;
|
||
|
|
||
|
std::string visit_string;
|
||
|
Visit visit{};
|
||
|
|
||
|
// read to string, convert to string stream, read from that stream again
|
||
|
// weird C++ gymnastics (or bad design by me)
|
||
|
getline(in, visit_string); // first string is always empty for some reason
|
||
|
while (getline(in, visit_string)) {
|
||
|
std::stringstream visit_stream(visit_string);
|
||
|
visit_stream >> visit;
|
||
|
patient.visits.push_back(visit);
|
||
|
}
|
||
|
|
||
|
return in;
|
||
|
// clang-format on
|
||
|
}
|