The code works, I just want to see if someone can help me cut lines in main only.

#include <iostream>
#include <sstream>
#include <windows.h>
#include <time.h>
#include <string>

using namespace std;

struct tm * timeinfo; // Holds information about time in form of struct

class Date
{
    public:
           int m_nMonth;
           int m_nDay;
           int m_nYear;
           
// Allocate function
    void setDate(int nMonth, int nDay, int nYear)
    {
         m_nMonth = nMonth;
         m_nDay = nDay;
         m_nYear = nYear;
    }
// Display function
    void displayDate()
    {
         cout << "Today's Date is: "
         << m_nMonth << "/"
         << m_nDay << "/"
         << m_nYear << endl;
    }
};

int main()
{
    Date cTodayDate;                             // Variable for class
    time_t rawtime;                              // Variable of type time_t
    string strMonth, strDay, strYear, dateTime;  // Variables to hold strings
    int nMonth, nDay, nYear;                     // Variables to hold actual
                                                 // numeric values
  
// Getting time from system 
    time ( &rawtime );
    timeinfo = localtime ( &rawtime );
// Making timeinfo from struct to string:: Www Mmm dd hh:mm:ss yyyy
    dateTime = asctime (timeinfo);
// Break down to get Month
    strMonth.append(dateTime,4,3);
    if(strMonth.compare("Jan") == 0) 
     nMonth = 1; 
    else if(strMonth.compare("Feb") == 0) 
     nMonth = 2; 
    else if(strMonth.compare("Mar") == 0) 
     nMonth = 3; 
    else if(strMonth.compare("Apr") == 0) 
     nMonth = 4; 
    else if(strMonth.compare("May") == 0) 
     nMonth = 5; 
    else if(strMonth.compare("Jun") == 0) 
     nMonth = 6; 
    else if(strMonth.compare("Jul") == 0) 
     nMonth = 7; 
    else if(strMonth.compare("Aug") == 0) 
     nMonth = 8; 
    else if(strMonth.compare("Sep") == 0) 
     nMonth = 9; 
    else if(strMonth.compare("Oct") == 0) 
     nMonth = 10; 
    else if(strMonth.compare("Nov") == 0) 
     nMonth = 11; 
    else if(strMonth.compare("Dec") == 0) 
     nMonth = 12; 
    else cout << "Error." << endl;
// Break down to get Day
    strDay.append(dateTime,8,2);
    istringstream ( strDay ) >> nDay;
// Break down to get Year
    strYear.append(dateTime,20,4);
    istringstream ( strYear ) >> nYear;
// Allocate in class
    cTodayDate.setDate(nMonth, nDay, nYear);
// Display in class
    cTodayDate.displayDate();
// Display for 4 seconds
    Sleep(4000);
    return 0;
}

Recommended Answers

All 11 Replies

Keep an array with the names of the months and search that instead of having that if/else block.

You are so right.

#include <iostream>
#include <sstream>
#include <windows.h>
#include <time.h>
#include <string>

using namespace std;

const int YEAR = 12;

struct tm * timeinfo; // Holds information about time in form of struct

class Date
{
    public:
           int m_nMonth;
           int m_nDay;
           int m_nYear;
           
// Set Date function
    void setDate(int nMonth, int nDay, int nYear)
    {
         m_nMonth = nMonth;
         m_nDay = nDay;
         m_nYear = nYear;
    }
// Display function
    void displayDate()
    {
         cout << "Today's Date is: "
         << m_nMonth << "/"
         << m_nDay << "/"
         << m_nYear << endl;
    }
};

int main()
{
    Date cTodayDate;                               // Variable for class
    string astrMonths[YEAR] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 
                               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
                                                   // Holds Array for Months
    time_t rawtime;                                // Variable of type time_t
    string *strMonth, *strDay, *strYear, *dateTime;// Variables to hold strings
    int *pnMonth, *pnDay, *pnYear;                 // Variables to hold actual
                                                   // numeric values
// Allocate memory
    dateTime = new string; 
    pnMonth = new (int);   strMonth = new string;
    pnDay = new (int);     strDay = new string;
    pnYear = new (int);    strYear = new string;
    
// Getting time from system 
    time ( &rawtime );
    timeinfo = localtime ( &rawtime );
// Making timeinfo from struct to string:: Www Mmm dd hh:mm:ss yyyy
    *dateTime = asctime (timeinfo);
// Break down to get Month
    (*strMonth).append(*dateTime,4,3);
// Loop to convert to numeric value
    for(int i = 0; i < YEAR; i++)
    {
        if(*strMonth == astrMonths[i])
        { 
            *pnMonth = i + 1; 
        }
    }
// Break down to get Day
    (*strDay).append(*dateTime,8,2);
    istringstream ( *strDay ) >> *pnDay;
// Break down to get Year
    (*strYear).append(*dateTime,20,4);
    istringstream ( *strYear ) >> *pnYear;
// Allocate in class
    cTodayDate.setDate(*pnMonth, *pnDay, *pnYear);
// Display in class
    cTodayDate.displayDate();
// Delete borrowed memory
    delete dateTime;
    delete pnMonth; delete strMonth;
    delete pnDay;   delete strDay;
    delete pnYear;  delete strYear;
// Display for 4 seconds
    Sleep(4000);
    return 0;
}

Two things:

  1. You should use ctime instead of time.h
  2. What is the reason for using std::string * instead of std::string for most of your strings?

1.Same thing it's just a matter of choice, switched it anyway.
2. Why not? If there is a reason why I shouldn't I'll switch it :D

You should use the <ctime> instead of the <time.h> because in ctime, all of the functions are declared in the the std:: namespace, whereas with time.h, they are all thrown into the global namespace.

I'll invert the question and ask you "Why?" I originally thought you were getting mixed up between C-strings (the char * variety) and std::string, but I'm not sure what your rationale is. There's the extra dereferencing step which is required to access the actual string that you totally avoid when the strings are not pointers.

I work on really small memory spaces so it has become a custom to dynamically allocate stuff.

Someone can correct me if I'm off-base on this, but in order to use the string pointer for anything, there has to be a string somewhere to point at. So, in reality you may be bringing a pointer into the mix that you don't need (at least in this program).

If you needed to pass the strings around, you could pass by reference.

Ok.

#include <iostream>
#include <sstream>
#include <windows.h>
#include <ctime>
#include <string>

using namespace std;

const int YEAR = 12;

struct tm * timeinfo; // Holds information about time in form of struct

class Date
{
    public:
           int m_nMonth;
           int m_nDay;
           int m_nYear;
           
// Set Date function
    void setDate(int nMonth, int nDay, int nYear)
    {
         m_nMonth = nMonth;
         m_nDay = nDay;
         m_nYear = nYear;
    }
// Display function
    void displayDate()
    {
         cout << "Today's Date is: "
         << m_nMonth << "/"
         << m_nDay << "/"
         << m_nYear << endl;
    }
};

int main()
{
    Date cTodayDate;                               // Variable for class
    string astrMonths[YEAR] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", 
                               "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
                                                   // Holds Array for Months
    time_t rawtime;                                // Variable of type time_t
    string strMonth, strDay, strYear, dateTime;// Variables to hold strings
    int *pnMonth, *pnDay, *pnYear;                 // Variables to hold actual
                                                   // numeric values
// Allocate memory
    pnMonth = new (int);   
    pnDay = new (int);     
    pnYear = new (int);    
    
// Getting time from system 
    time ( &rawtime );
    timeinfo = localtime ( &rawtime );
// Making timeinfo from struct to string:: Www Mmm dd hh:mm:ss yyyy
    dateTime = asctime (timeinfo);
// Break down to get Month
    strMonth.append(dateTime,4,3);
// Loop to convert to numeric value
    for(int i = 0; i < YEAR; i++)
    {
        if(strMonth == astrMonths[i])
        { 
            *pnMonth = i + 1; 
        }
    }
// Break down to get Day
    strDay.append(dateTime,8,2);
    istringstream ( strDay ) >> *pnDay;
// Break down to get Year
    strYear.append(dateTime,20,4);
    istringstream ( strYear ) >> *pnYear;
// Allocate in class
    cTodayDate.setDate(*pnMonth, *pnDay, *pnYear);
// Display in class
    cTodayDate.displayDate();
// Delete borrowed memory
    delete pnMonth; 
    delete pnDay;  
    delete pnYear; 
// Display for 4 seconds
    Sleep(4000);
    return 0;
}

>>(Ravenous)You should use ctime instead of time.h
>(Nandomo)Same thing it's just a matter of choice, switched it anyway.
Actually, Ravenous is correct, and there is a difference.

The <ctime> header is the modern (post-Standard) version of <time.h> and should always be used for modern code. It defines and uses the std namespace and has a couple other minor changes. The same applies to <stdlib.h>, <stdio.h>, <math.h>, <ctype.h> and a few others. The newer versions are <cstdlib>, <cstdio>, <cmath> and <cctype> respectively.

@jonsca:
You are correct. Under certain circumstances, a pointer helps boost performance, but it is another integer-sized (or larger) chunk of memory that uses space. If you have space limitations, you really should avoid them in favor of passing an actual object by (constant) reference.

@Nandomo
You still allocate the int variables dynamically, for which there is no reason.
If you find yourself writing the keyword new, you generally should stop and try to find good reasons why you need to use new. If you can't, you shouldn't use it.
Doubly so when you find yourself writing delete. Due to RAII (which you aren't conforming to here), you rarely should have any manual deletes in your program, unless you're currently implementing a container class of some sort (and even then, it's not needed if you build it on other containers).

I think you can get it in fewer lines, but I'm not sure that it makes anything clearer. Anyway, here's a method that does it in one line:

int main()
{
    Date cTodayDate;
    /* Make a std::string with the possible month values in it */
    string months("JanFebMarAprMayJunJulAugSepOctNovDec");
    time_t rawtime;
    string strMonth, strDay, strYear, dateTime;
    /* I made these into actual variables too ;o) */
    int month, day, year;  
 
    /* Getting time from system */ 
    time ( &rawtime );
    timeinfo = localtime ( &rawtime );

    /* Making timeinfo from struct to string:: Www Mmm dd hh:mm:ss yyyy */
    dateTime = asctime (timeinfo);

    /* Break down to get Month */
    strMonth = dateTime.substr(4,3);          // This is safer than using append()
    month = 1 + (months.find(strMonth)/3);    // Get the month here

    /* Rest of program follows */

    return 0;
}

The possible values of strMonth are declared in a std::string on line 5 and the actual conversion to a number is done on line 20. I also changed line 19 from using std::string::append() , since this will just add the part from dateTime to the end of strMonth this is OK if strMonth is empty, but not if it's got something in it. Since you actually just want strMonth to contain the month string, you might as well not take the risk!

Like I said, I'm not sure if it's any clearer but it is only a single line, which is about as cut-down as you can get :)

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.