Thread: asctime woes

  1. #1
    Registered User
    Join Date
    Apr 2005
    Posts
    12

    asctime woes

    I am currently working on a program that will calculate the number of hours I have worked for any given day. What I have is as follows:
    Code:
    //////////////////////////////////////////////////////////////////////////
    // calculates and outputs the number of hours worked for any given day  //
    //////////////////////////////////////////////////////////////////////////
    
    #include <iostream>
    #include <fstream>
    #include <time.h>
    
    time_t start, end;
    struct tm * IN;
    struct tm * OUT;
    double diff;
    
    void timeIN()
    {
     time (&start); //Get the current time
     IN = localtime (&start); //Adjust to the local timezone
     cout << "Time in: " << asctime (IN); //Print the time IN
    }
    
    void timeOUT()
    {
     time (&end); //Get the current time
     OUT = localtime (&end); //Adjust to the local timezone
     cout << "Time out: " << asctime (OUT); //Print the time OUT
    }
    
    void timeWORKED()
    {
     diff = (difftime (end, start))/3600; //Calculate the number of hours worked
     cout << "Hours worked: " << diff << "\n";
    }
    
    void outPUT()
    {
     cout << "Outputting to timeworked.txt\n";
     ofstream workFile ("timeworked.txt"); //Open timeworked.txt for output
     if ( !workFile.is_open() ) { //Check to see if the file is not open
      cout << "Error: Failed to open file\n"; //If the file is not open give an Error
      } else { //Otherwise output the data to the file
      workFile << "Time in: " << asctime (IN);
      workFile << "time out: " << asctime (OUT);
      workFile << "Hours worked: " << diff << "\n";
      workFile.close();
      }
    }
    
    void error()
    {
     cout << "Error!!!\n";
    }
    
    void menu()
    {
     int opt; //Option to switch
     cout << "[1] Enter your time IN \n";
     cout << "[2] Enter your time OUT \n";
     cout << "[3] Calculate your total time Worked\n";
     cout << "[4] Output to a file\n";
     cout << "[5] Exit\n";
     cout << "Enter your choice: ";
     cin >> opt; //Get the otption to switch
          switch ( opt ) { // switch the option
         case 1:
          timeIN();
          break;
         case 2:
          timeOUT();
          break;
         case 3:
          timeWORKED();
          break;
         case 4:
          outPUT();
          break;
         case 5:
          exit(0);
         default:
          error();
          break;
         }
    }
    
    int main()
    {
     while (1) {
     menu();
     }
    return 0;
    }
    At a quick glance the program gives off the illusion that it is working, however, it is not. The functions void timeIN() (ln 14) and void timeOUT() (ln 21) print two unique times and dates by way of asctime(IN) (ln 18) and asctime(OUT) (ln 25), as they should. Sadly, in my function void outPUT() (ln 34), the output given by asctime(IN) (ln 41) and asctime(OUT) (42) is not identical to the output given by the same calls in past lines. What could be causing this?

  2. #2
    Registered User mitakeet's Avatar
    Join Date
    Jun 2005
    Location
    Maryland, USA
    Posts
    212
    This worked perfectly fine for me:

    Code:
    #include <iostream>
    #include <fstream>
    #include <ctime>
    
    using namespace std;
    
    time_t start, end;
    struct tm *IN, *OUT;
    double diff;
    
    void timeIN() {
        time (&start);                                //Get the current time
        IN = localtime (&start);                      //Adjust to the local timezone
        cout << "Time in: " << asctime (IN);          //Print the time IN
    }
    
    void timeOUT() {
        time (&end);                                  //Get the current time
        OUT = localtime (&end);                       //Adjust to the local timezone
        cout << "Time out: " << asctime (OUT);        //Print the time OUT
    }
    
    void timeWORKED() {
        diff = (difftime (end, start))/3600;          //Calculate the number of hours worked
        cout << "Hours worked: " << diff << "\n";
    }
    
    void outPUT() {
        cout << "Outputting to timeworked.txt\n";
        ofstream workFile ("timeworked.txt");         //Open timeworked.txt for output
        if ( !workFile.is_open() ) {                  //Check to see if the file is not open
            cout << "Error: Failed to open file\n";   //If the file is not open give an Error
        }                                             //Otherwise output the data to the file
        else {
            workFile << "Time in: " << asctime (IN);
            workFile << "time out: " << asctime (OUT);
            workFile << "Hours worked: " << diff << "\n";
            workFile.close();
        }
    }
    
    void error() {
        cout << "Error!!!\n";
    }
    
    void menu() {
        int opt;
        cout << "[1] Enter your time IN \n";
        cout << "[2] Enter your time OUT \n";
        cout << "[3] Calculate your total time Worked\n";
        cout << "[4] Output to a file\n";
        cout << "[5] Exit\n";
        cout << "Enter your choice: ";
        cin >> opt;//you need error checking and recover here!
        switch ( opt ) {
            case 1: timeIN(); break;
            case 2: timeOUT(); break;
            case 3: timeWORKED(); break;
            case 4: outPUT(); break;
            case 5: exit(0);
            default: error();
        }
    }
    
    int main() {
        while (1) {
            menu();
        }
        return 0;
    }

    Free code: http://sol-biotech.com/code/.

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw

  3. #3
    Registered User
    Join Date
    Apr 2005
    Posts
    12
    If you open the file timeworked.txt you get this:
    Code:
    Time in: Thu Jun 23 12:41:24 2005
    time out: Thu Jun 23 12:41:24 2005
    Hours worked: 0.000277778
    However, the original data printed by asctime(IN) is:
    Code:
    Time in: Thu Jun 23 12:41:23 2005
    While the data printed by asctime(OUT) is:
    Code:
    Time out: Thu Jun 23 12:41:24 2005
    Last edited by magis; 06-23-2005 at 10:47 AM.

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > struct tm * IN;
    > struct tm * OUT;
    You can't have two localtime's on the go at the same time. If you print this pointer, you should find them both pointing at the same block of memory.

    Try these bits, with other appropriate adjustments to your code.
    struct tm IN;
    struct tm OUT;
    IN = *localtime (&start);
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User mitakeet's Avatar
    Join Date
    Jun 2005
    Location
    Maryland, USA
    Posts
    212
    Read up on the documentation; I believe localtime may return a pointer to a local buffer, in which case IN and OUT would point to exactly the same memory location.

    Free code: http://sol-biotech.com/code/.

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw

  6. #6
    Registered User
    Join Date
    Apr 2005
    Posts
    12
    Mission accomplished . But I am a little confused as to why a reference would work and not a pointer, would someone please explain this? To be honest... I just threw the reference operator in there because I remember reading from my book that references and pointers are almost exactly the same.

    And for those who have the same problem, this is the finished product:
    Code:
    //////////////////////////////////////////////////////////////////////////
    // calculates and outputs the number of hours worked for any given day  //
    //////////////////////////////////////////////////////////////////////////
    
    #include <iostream>
    #include <fstream>
    #include <time.h>
    
    time_t start, end;
    struct tm IN;
    struct tm OUT;
    double diff;
    
    void timeIN()
    {
     time (&start); //Get the current time
     IN = *localtime (&start); //Adjust to the local timezone
     cout << "Time in: " << asctime (&IN); //Print the time IN
    }
    
    void timeOUT()
    {
     time (&end); //Get the current time
     OUT = *localtime (&end); //Adjust to the local timezone
     cout << "Time out: " << asctime (&OUT); //Print the time OUT
    }
    
    void timeWORKED()
    {
     diff = (difftime (end, start))/3600; //Calculate the number of hours worked
     cout << "Hours worked: " << diff << "\n";
    }
    
    void outPUT()
    {
     cout << "Outputting to timeworked.txt\n";
     ofstream workFile ("timeworked.txt"); //Open timeworked.txt for output
     if ( !workFile.is_open() ) { //Check to see if the file is not open
      cout << "Error: Failed to open file\n"; //If the file is not open give an Error
      } else { //Otherwise output the data to the file
      workFile << "Time in: " << asctime (&IN);
      workFile << "time out: " << asctime (&OUT);
      workFile << "Hours worked: " << diff << "\n";
      workFile.close();
      }
    }
    
    void error()
    {
     cout << "Error!!!\n";
    }
    
    void menu()
    {
     int opt; //Option to switch
     cout << "[1] Enter your time IN \n";
     cout << "[2] Enter your time OUT \n";
     cout << "[3] Calculate your total time Worked\n";
     cout << "[4] Output to a file\n";
     cout << "[5] Exit\n";
     cout << "Enter your choice: ";
     cin >> opt; //Get the otption to switch
          switch ( opt ) { // switch the option
         case 1:
          timeIN();
          break;
         case 2:
          timeOUT();
          break;
         case 3:
          timeWORKED();
          break;
         case 4:
          outPUT();
          break;
         case 5:
          exit(0);
         default:
          error();
          break;
         }
    }
    
    int main()
    {
     while (1) {
     menu();
     }
    return 0;
    }

  7. #7
    Registered User mitakeet's Avatar
    Join Date
    Jun 2005
    Location
    Maryland, USA
    Posts
    212
    You are putting the DE-reference operator, which then sets up for a copy to the NON-pointer tm struct. Thus you are making a copy of the actual data instead of a copy of the pointer. Day and night difference!

    Free code: http://sol-biotech.com/code/.

    It is not that old programmers are any smarter or code better, it is just that they have made the same stupid mistake so many times that it is second nature to fix it.
    --Me, I just made it up

    The reasonable man adapts himself to the world; the unreasonable one persists in trying to adapt the world to himself. Therefore, all progress depends on the unreasonable man.
    --George Bernard Shaw

  8. #8
    Registered User
    Join Date
    Apr 2005
    Posts
    12
    That makes sense, thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segment woes
    By astrodude15 in forum C Programming
    Replies: 2
    Last Post: 06-04-2007, 06:45 AM
  2. Segment woes
    By astrodude15 in forum C Programming
    Replies: 3
    Last Post: 06-01-2007, 10:10 AM
  3. 2 am complex double conversion woes
    By Roule in forum C++ Programming
    Replies: 1
    Last Post: 10-14-2004, 02:53 PM
  4. DLL and std::string woes!
    By Magos in forum C++ Programming
    Replies: 7
    Last Post: 09-08-2004, 12:34 PM
  5. asctime()
    By Draco in forum C Programming
    Replies: 3
    Last Post: 01-14-2004, 04:10 PM