Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

USING C++ : Problem B: Birthdays (20 points) Make a program that reads a list of

ID: 3823017 • Letter: U

Question

USING C++ :

Problem B: Birthdays (20 points) Make a program that reads a list of birthdays from a file called "birthdays.txt" (please make sure this name is exact. You will then ask the user to input a date and you are required to find: (1) who has the next birthday, (2) how many days away that birthday is from the input date and (3) how old the person will be on that birthday. (Note: you DO need to take into account leap year (see example 3). The format of "birthdays.txt" will be: name put together with underscores mm/dd/yyyy You may may assume there is at least one birthday in "birthdays txt". You may also assume the date entered is valid. You do not need to check if the file opened correctly. Example 1 (user input is underlined: Current date 12112040 Next birthday: Mary Rasmussen. in 12 days will turn 81

Explanation / Answer

PROGRAM CODE:

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include <string>
using namespace std;

struct birthday
{
   string name;
   int year;
   int month;
   int day;
};


void readBirthdaysFile(struct birthday birthdays[], int &size)
{
   ifstream in("birthdays.txt");
   string line;
   while(getline(in, line))
   {
       istringstream iss(line);
       string date, colon;
       int dividerIndex = 0;
       if(!(iss>>birthdays[size].name>>colon>>date))
       {
           cout<<"Format of the file is wrong";
           exit(1);
       }
       //calculating the indices of '/' and splitting out the number
       dividerIndex = date.find("/");
       string subString = date.substr(dividerIndex+1, (date.length()-(dividerIndex+1)));
       birthdays[size].month = atoi(date.substr(0, dividerIndex).c_str());
       birthdays[size].day = atoi(date.substr(dividerIndex+1, 2).c_str());
       dividerIndex = subString.find("/");
       birthdays[size].year = atoi(subString.substr(dividerIndex+1, 4).c_str());
       size++;
   }
}

//returns the number of days in the month
int getDaysInMonth(int month, int year)
{
   int days = 0;
   bool isLeapYear = false;
   if ( year%400 == 0)
       isLeapYear = true;
   else if ( year%100 == 0)
       isLeapYear = false;
   else if ( year%4 == 0 )
       isLeapYear = true;
   switch(month)
   {
   case 1:
   case 3:
   case 5:
   case 7:
   case 8:
   case 10:
   case 12: days = 31; break;
   case 2 : if(isLeapYear)
               days = 29;
           else days = 28; break;
   case 4:
   case 6:
   case 9:
   case 11: days = 30; break;

   }
   return days;
}

//displays the output which is the next birthday , the days remaining and the age
void findNextBirthday(struct birthday birthdays[], int size, string currentDate)
{
   int month, day, year, dividerIndex = 0;
   dividerIndex = currentDate.find("/");
   string subString = currentDate.substr(dividerIndex+1, (currentDate.length()-(dividerIndex+1)));
   month = atoi(currentDate.substr(0, dividerIndex).c_str());
   day = atoi(currentDate.substr(dividerIndex+1, 2).c_str());
   dividerIndex = subString.find("/");
   year = atoi(subString.substr(dividerIndex+1, 4).c_str());

   int minMonth = 13, minDay = 32, index = -1, days = 0, counterMonth;
   for(int i=0; i<size; i++)
   {
       if(birthdays[i].month >= month)
       {
           if(birthdays[i].month < minMonth)
           {
               minMonth = birthdays[i].month;
               minDay = birthdays[i].day;
               index = i;
           }
           else if(birthdays[i].month == minMonth)
           {
               if(birthdays[i].day < day)
                   minDay = birthdays[i].day;
               index = i;
           }
       }
   }
   //If there is no birthday in the same year after the current date
   //then we shall search in the next year
   if(index == -1)
   {
       for(int i=0; i<size; i++)
       {
           if(birthdays[i].month < minMonth)
               {
                   minMonth = birthdays[i].month;
                   minDay = birthdays[i].day;
                   index = i;
               }
               else if(birthdays[i].month == minMonth)
               {
                   if(birthdays[i].day < day)
                       minDay = birthdays[i].day;
                   index = i;
               }
           }
   }

   //couting the remaining days
   if(birthdays[index].month == month)
       days = birthdays[index].day - day;
   else
   {
       //days remaining in the current month
       days = getDaysInMonth(month, year) - day;
       counterMonth = month+1;
       if(counterMonth>12)
       {
           year = year+1;
           counterMonth = 1;
       }
       //days in between the two months
       while(counterMonth != birthdays[index].month)
       {
           days += getDaysInMonth(counterMonth, year);
           counterMonth++;
           if(counterMonth>12)
           {
               year = year+1;
               counterMonth = 1;
           }
       }
       //days in the birthday month
       days += birthdays[index].day;
   }
   cout<<"Next Birthday: ";
   cout<<birthdays[index].name<<" "<<"in "<<days<<" days will turn "<<(year - birthdays[index].year);

}


int main() {
   struct birthday birthdays[100];
   int size = 0;
   string currentDate = "";
   //reading the data and putting it in struct
   readBirthdaysFile(birthdays, size);
   cout<<"Current date? ";
   cin>>currentDate;
   findNextBirthday(birthdays, size, currentDate);
   return 0;
}

OUTPUT:

Run #1:

Current date?

2/20/2017

Next Birthday:

Martin_Hughes

in 21 days

will turn 41

Run #2:

Current date?

1/1/2040

Next Birthday:

Mary_Rasmussen

in 12 days

will turn 53

Run #3:

Current date?

2/20/2016

Next Birthday:

Martin_Hughes

in 22 days

will turn 40