overloading << and >> operator and converting types during file writing and reading

Hello everyone,
I am working on an assignment.

Brief Specifications:
Class Song
Data members: Title(string), Artist(string), Length(Time, an object).
NB: length is the length of the song. It takes a time object (hh:mm:ss)but when saving to file, time should be saved as an int converted to seconds. This is my code so far
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
  // song.h
#include "time.h"  // contains data for time management
#include <string>	// std::string
#define DELIM '|'
class Song 
{
private:
// Data members
    string title;
    string artist;
    Time length;
	
public:
// constructors
    Song();
    Song(string pTitle, string pArtist, Time pLength);

// destructor
    ~Song();

// member functions
    void setTitle(string pTitle) {title = pTitle;}
    void setArtist(string pArtist){artist = pArtist;}
    void setLength(Time pLength) {length = pLength;}

    string getTitle ()const  { return title; }
    string getArtist ()const { return artist; }
    Time getLength()const   { return length; }
};
// overloading input and output operators
ostream &operator<<(ostream &os, const Song &song);
istream &operator >> (istream &is, Song &song);

// in song.cpp
// overloading the << for saving a Song object to file
ostream & operator<<(ostream & os, const Song & song)
{
    int len = song.getLength().getHour() * 3600 +
	      song.getLength().getMinutes() * 60 +
	      song.getLength().getSeconds();

    os << song.getTitle() << DELIM;
    os << song.getArtist() << DELIM;
    os << len;
    return os;
}

// This is where my problem is
// overloading the >> operator for input stream and reading from file
istream & operator >> (istream & is, Song & song)
{
    string str;
    Time t;
    int total;

    getline(is, str, DELIM);
    song.setTitle(str);

    getline(is, str, DELIM);
    song.setArtist(str);

    is >> total;
    is.get();
	
    // Reconvert this int to time
    int tmpHr = total / 3600;  // this extracts the hours correctly
    int tmpMin = (total % 3600) * 60;   // trying to get the minutes
    int tmpSec = (total % 3600) % 60; // trying to get the seconds

    t.setHour(tmpHr);
    t.setMinutes(tmpMin);
    t.setSeconds(tmpSec);
    
     song.setLength(t);
     return is;	
}

// time.h
class Time
{
private:
    // data members
    int hours;
    int minutes;
    int seconds;


I have a test function to show song(to check whether i have extracted time correctly)
1
2
3
4
5
6
void showSong(const Song & song)
{
	cout << " Song Title: " << song.getTitle() << endl;
	cout << " Artist    : " << song.getArtist() << endl;
	cout << " Length    : " << song.getLength() << endl;
}


Any tips i.e reading the length from int(seconds) and extracting hr, mins & seconds?
from int(seconds) and extracting hr, mins & seconds
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <chrono>

int main()
{
    std::cout << "Enter number of seconds \n";
    int total_seconds{};
    std::cin >> total_seconds;//input validation here

    std::time_t seconds{total_seconds}; // intitialize time_t object with total_seconds
    std::tm* p = gmtime(&seconds); // http://www.cplusplus.com/reference/ctime/gmtime/

    std::cout << "days = " << p->tm_yday << "\n";
    std::cout << "hours = " << p->tm_hour << "\n";
    std::cout << "minutes = " << p->tm_min  << "\n";
    std::cout << "seconds = " << p->tm_sec << "\n";
}
edit: gunnerfunner beat me to it

What I'd recommend you is to use chrono. Chrono is basically time.h for C++, but it has more functionalities and personally I see no reason to use time.h instead. Chrono has a duration cast that can be used to extract hours/mins/secs fairly easily.

http://www.cplusplus.com/reference/chrono/duration_cast/
Last edited on
Line 67: int tmpMin = (total % 3600) / 60; // Note: Division

In order to get the seconds value correctly it needs to be saved with an appending delimiter as well. If you want to use >> any whitespace would do.
Thanks all. I wonder why we could not just use chrono instead of making another time object on our own.

@gunnerfunner & @Golden Lizard I really wished we were allowed to use this chrono library.

@coder777, thanks for citing that line.
Topic archived. No new replies allowed.