// DOCTORS.CPP - Doctor's Office Scheduling Program // All class implementations are in this file. #include "doctors.h" //.........global function .............. // Display a question, ask for yes or no answer, // return 1 if Y pressed, otherwise return 0. #include // for toupper() int getYN( const char * st ) { char ch; cout << st << " [Y/n]: "; cin >> ch; cin.ignore(80,'\n'); if( toupper(ch) == 'Y' ) return 1; return 0; } //.................. TimeSlot ....................... unsigned TimeSlot::StartHour = 8; unsigned TimeSlot::ApptLen = 15; // Compare the intValues of two time slots. bool TimeSlot::operator <( const TimeSlot & rtOp ) const { return intValue < rtOp.intValue; } // Compare the intValues of two time slots. bool TimeSlot::operator ==( const TimeSlot & rtOp ) const { return intValue == rtOp.intValue; } istream & operator >>( istream & inp, TimeSlot & T ) { unsigned h, m; inp >> dec >> h; inp.get(); // skip the ":" inp >> m; unsigned aph = 60 / TimeSlot::ApptLen; if( h < T.StartHour ) // afternoon hour? h += 12; // add 12 to hours T.intValue = ((h - TimeSlot::StartHour)* aph) + (m / TimeSlot::ApptLen); return inp; } ostream & operator <<( ostream & os, const TimeSlot & T ) { unsigned aph = 60 / T.ApptLen; // 4 = 60 / 15 unsigned h = (T.intValue / aph ) + T.StartHour; // (S / 4) + 8 unsigned m = (T.intValue % aph ) * T.ApptLen; // (S % 4) * 15 char oldfill = os.fill('0'); os << setw(2) << h << ':' << setw(2) << m; os.fill( oldfill ); return os; } //................. DailySchedule ................... DailySchedule::DailySchedule() { appointments.resize( MaxTimeSlots ); for(unsigned i = 0; i < MaxTimeSlots; i++) appointments[i].SetTime( i ); } int DailySchedule::IsTimeSlotFree( const TimeSlot & aTime ) const { unsigned n = aTime.AsInteger(); return !appointments[n].IsScheduled(); } void DailySchedule::SetAppointment( const Appointment & app ) { unsigned n = app.GetTime().AsInteger(); appointments[n] = app; } void DailySchedule::ShowAppointments( ostream & os ) const { for(unsigned i = 0; i < MaxTimeSlots; i++) { if( appointments[i].IsScheduled()) os << appointments[i].GetTime() << " --> " << appointments[i].GetPatientName() << endl; } } ostream & operator <<( ostream & os, const DailySchedule & DS ) { for(unsigned i = 0; i < DS.MaxTimeSlots; i++) { os << DS.appointments[i].GetTime(); if( DS.appointments[i].IsScheduled()) os << " *** "; else os << " "; if( i % 4 == 3 ) os << '\n'; } return os; } //...................... Doctor ....................... vector Doctor::doctorNames; // Static data member. Doctor::Doctor() { id = 0; } int Doctor::AddToSchedule( const Appointment & app ) { if( schedule.IsTimeSlotFree( app.GetTime())) { schedule.SetAppointment( app ); return 1; } return 0; } void Doctor::ShowAppointments( ostream & os ) const { os << "Appointments for Dr. " << lastName << '\n' << ".................................." << '\n'; schedule.ShowAppointments( os ); os << endl; } //................... Appointment ...................... Appointment::Appointment ( const TimeSlot & aTime, unsigned docNum, const Patient & aPatient ) { timeSlot = aTime; doctorNum = docNum; patientName = aPatient.GetLastName() + ", " + aPatient.GetFirstName(); } // When comparing appointments, we use only the timeSlot property. bool Appointment::operator <( const Appointment & rtOp ) const { return timeSlot < rtOp.timeSlot; } // When comparing appointments, we use only the timeSlot property. bool Appointment::operator ==( const Appointment & rtOp ) const { return timeSlot == rtOp.timeSlot; } ostream & operator <<( ostream & os, const Appointment & A ) { os << "Dr. " << Doctor::GetDoctorName(A.doctorNum) << ", " << "Time: " << A.timeSlot; return os; } //...................... Patient .............................. void Patient::InputName() { cout << "Patient's last name: "; #ifdef _MSC_VER const bool IsConsole = true; getline( cin, lastName, '\n', IsConsole ); cout << "Patient's first name: "; getline( cin, firstName, '\n', IsConsole ); #else getline( cin, lastName ); cout << "Patient's first name: "; getline( cin, firstName ); #endif } // Display list of doctor names and numbers. Let user // enter a number, and return this as the function result. unsigned Patient::ChooseDoctor() const { const vector dnames = Doctor::GetDoctorNames(); for(unsigned i = 0; i < dnames.size(); i++) cout << i << ": " << dnames[i] << '\n'; unsigned n = 0; int ok = 0; do { cout << "Enter a doctor number: "; cin >> n; cin.ignore(255,'\n'); if( n >= dnames.size() ) cout << "Number out of range!\n"; else ok = 1; } while( !ok ); return n; } TimeSlot Patient::ChooseTimeSlot( const Doctor & D ) const { cout << '\n' << "Daily Schedule of Dr. " << D.GetLastName() << '\n' << "........................................" << '\n' << D.GetSchedule() << '\n' << "Enter a time (format hh:mm): "; TimeSlot aSlot; cin >> aSlot; return aSlot; } ostream & operator <<( ostream & os, const Patient & P ) { os << "Patient " << P.firstName << ' ' << P.lastName << '\n' << "has been scheduled as follows:" << '\n' << P.nextVisit << endl; return os; } //................ Scheduler ................. // Initialize the doctor names from a file. The first input // line is an integer specifying the number of doctors. Scheduler::Scheduler( vector & docs ) :doctors(docs) { ifstream dnameFile( "doctors.txt" ); if( !dnameFile ) { cout << "Cannot open input file! Aborting program.\n"; abort(); } unsigned numberOfDoctors; dnameFile >> numberOfDoctors; dnameFile.ignore( 255, '\n' ); string temp; for(unsigned i = 0; i < numberOfDoctors; i++) { doctors[i].SetId( i ); getline( dnameFile, temp ); doctors[i].SetLastName( temp ); Doctor::AddDoctorName( temp ); } } // Write each doctor's list of appointments, // showing time and patient name for each. void Scheduler::PrintAllAppointments(const char * fileName) { ofstream ofile( fileName ); if( ofile ) for(unsigned i = 0; i < doctors.size(); i++) doctors[i].ShowAppointments( ofile ); } void Scheduler::ScheduleAllAppointments() { while( ScheduleOneAppointment() ) continue; } // Choose a doctor, input patient name, and // ask for a particular time slot. Make the // appointment, and display the results. int Scheduler::ScheduleOneAppointment() { // Get patient name, let patient request a doctor. Patient aPatient; aPatient.InputName(); unsigned doctorNum = aPatient.ChooseDoctor(); Doctor & theDoc = doctors[doctorNum]; while( !aPatient.IsScheduled() ) { // Patient chooses a time slot. Construct an appointment // from the time slot, doctor number, and patient name. TimeSlot aTime = aPatient.ChooseTimeSlot( theDoc ); Appointment app( aTime, doctorNum, aPatient ); // Try to schedule the patient for a particular time // slot with the chosen doctor. If successful, add the // appointment time to the patient's record; if not, // display an error message. if( theDoc.AddToSchedule( app )) aPatient.SetAppointment( app ); else cout << "Sorry, Dr. " << theDoc.GetLastName() << " is not available at that time. " << endl; } cout << aPatient; return getYN("Continue?"); }