Solved

overloading the extraction operator

Posted on 2003-10-26
3
256 Views
Last Modified: 2010-04-01
Hello experts:


I need to fill a list with objects.  (See fill_list function below).
I also am trying to create a function to overload the extraction operator in order to read the objects into the list.
I can't figure out how to do this. Any help/suggestions would be GREATLY appreciated.
(Excuse the appearance of the code.  For some reason when I copy and paste from my source code it gets misaligned.)

//file name: club_member.cpp

#include <string>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <sstream>
#include <list>

using namespace std;

class ClubMember
{
public:
      ClubMember();
      ClubMember(string a_first_name, string a_middle_init, string a_last_name,
                          string a_membership_yr);
//            ~ClubMember();
            
            string get_first_name() const;
            string get_middle_init() const;
            string get_last_name() const;
            string get_membership_yr() const;
            string get_last_first_name() const;
            string get_first_last_name() const;

            void set_first_name(string new_first_name);
            void set_middle_init(string new_middle_init);
            void set_last_name(string new_last_name);
            void set_membership_yr(string new_membership_yr);
            void get_last_first_name(string new_last_name, string new_first_name) const;
            void get_first_last_name(string newfirst_name, string new_last_name) const;

            int operator<(ClubMember&);
            int operator>(ClubMember&);

            friend istream& operator>>(istream& in_stream, ClubMember& a_member);
            friend ostream& operator>>(ostream& out_stream, ClubMember& a_member);

      private:
            string first_name;
            string middle_init;
            string last_name;
            string membership_yr;
};

void fill_list(list<ClubMember>&, istream&);

template <class T>
inline void print_list(T& L, ostream& outfile, char* optional="")
{
      typename T::iterator pos;

      outfile << optional << endl;
      
      for (pos = L.begin(); pos != L.end(); ++pos)
      {
            outfile << *pos << ' ';
      }
      outfile << endl;
}

int main()
{
      
      list<ClubMember> member_list;
      ifstream fin;
      ofstream fout;
      
      fin.open("C:\\CSC311\\Files\\member_in.txt");
      
      if (fin.fail())
      {
            cout << "Failed to open input file" << endl;
            exit(1);
      }

      fout.open("C:\\CSC311\\Files\\member_out.txt");
      
      if (fout.fail())
      {
            cout << "Failed to open output file" << endl;
            exit(1);
      }

      fill_list(member_list, fin);
      print_list(member_list, fout, "Sorted Member List:\n");
      fin.close();
      fout.close();
      return 0;
}

void fill_list(list<ClubMember>& member_list, istream& infile)
{
      ClubMember temp;
      
      while (!infile.eof())
      {
            infile >> temp;
            member_list.push_back(temp);
      }
}

ClubMember::ClubMember() { }      

ClubMember::ClubMember(string a_first_name, string a_middle_init, string a_last_name,
                              string a_membership_yr)
{
          first_name = a_first_name;
          middle_init = a_middle_init;
          last_name = a_last_name;
          membership_yr = a_membership_yr;
}

string ClubMember::get_first_name() const
{
      return first_name;
}

string ClubMember::get_middle_init() const
{
      return middle_init;
}

string ClubMember::get_last_name() const
{
      return last_name;
}

string ClubMember::get_membership_yr() const
{
      return membership_yr;
}

string ClubMember::get_last_first_name() const
{
      return last_name + first_name;
}

void ClubMember::set_first_name(string new_first_name)
{
      first_name = new_first_name;
}

void ClubMember::set_middle_init(string new_middle_init)
{
      middle_init = new_middle_init;
}

void ClubMember::set_last_name(string new_last_name)
{
      last_name = new_last_name;
}

void ClubMember::set_membership_yr(string new_membership_yr)
{
      membership_yr = new_membership_yr;
}
            
istream& operator>>(istream& infile, ClubMember& a_member)
{
      string f_name;
      string m_init;
      string l_name;
      string mbr_yr;
      string in_line;

      getline(infile, in_line);
      in_line >> a_member.set_first_name(f_name) >> 
                >> a_member.set_middle_init(m_init) >>
                  >> a_member.set_last_name(l_name) >>
                  >> a_member.set_membership_yr(mbr_yr);
      return infile;
}

ostream& operator<<(ostream& outfile, ClubMember& a_member)
{
      return outfile;
}  

0
Comment
Question by:deekakes
  • 2
3 Comments
 
LVL 8

Expert Comment

by:mnashadka
ID: 9623156
Since it's a friend, you don't need to use the set functions, you can insert directly into the ClubMember, like:

istream& operator>>(istream& infile, ClubMember& a_member)
{
  infile >> a_member.first_name >> a_member.middle_init >> a_member.last_name >> a_member.membership_yr;
 
  return infile;
}

As for fill_list, just create ClubMember objects, and call push_back for each of them onto the list:
void fill_list(list<ClubMember>& member_list, istream& infile)
{
  ClubMember cm;
  while(infile >> cm)
  {
    member_list.push_back(cm);
  }
}

Hope this helps.
0
 

Author Comment

by:deekakes
ID: 9623360
Thank you....your answer got me headed in the right direction.  I now have the following problem:

 I have a data file consisting of:

Henry J Jones   1967  
Shakespeare William    1930  
John L Smith     1961
Tina Tucker  1999
Jay Bird  2002

But what the program prints is 1111
                                            1111
                                            1111
                                            1111
 
 I also get a compiler warning of
"C:\CSC311\Lab Programs\ClubMember\club_member.cpp
(173) : warning C4761: integral size mismatch in argument; conversion supplied"

I added the following to the program:

istream& operator>>(istream& infile, ClubMember& a_member)
{
      infile >> a_member.first_name >> a_member.middle_init
               >> a_member.last_name >> a_member.membership_yr;
      return infile;
}

ostream& operator<<(ostream& outfile, ClubMember& a_member)
{
      outfile << a_member.set_first_name << a_member.set_middle_init
                << a_member.set_last_name << a_member.set_membership_yr;
      return outfile;
}  
I was wondering if there might be something wrong with my print_list function.(?)

0
 
LVL 8

Accepted Solution

by:
mnashadka earned 80 total points
ID: 9623427
In the stream extraction operator, you're printing the address of member functions.  Change:
    outfile << a_member.set_first_name << a_member.set_middle_init
              << a_member.set_last_name << a_member.set_membership_yr;

To
    outfile << a_member.first_name << a_member.middle_init
              << a_member.last_name << a_member.membership_yr;

And in your friend declaration, you have an ostream >> operator, which should be the ostream << operator.  I'm sure that's just a typo.

Also, you may need some logic to figure out whether or not to read the 4th element, since you don't always have 4 elements.  Maybe something like:
istream& operator>>(istream& infile, ClubMember& a_member)
{
  infile >> a_member.first_name >> a_member.middle_init
    >> a_member.last_name;

  // If last_name was actually a number, move last_name to membership_yr
  // and middle_init to last_name
  if(isdigit(a_member.last_name[0])) // Check to see if the first character is an int
  {
    a_member.membership_yr = a_member.last_name;
    a_member.last_name = a_member.middle_init;
    a_member.middle_init = "";
  }
  else
  {
    // Read in the 4th element
    infile >> a_member.membership_yr;
  }
  return infile;
}
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

867 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now