Solved

overloading the extraction operator

Posted on 2003-10-26
3
279 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
Many modern programming languages support the concept of a property -- a class member that combines characteristics of both a data member and a method.  These are sometimes called "smart fields" because you can add logic that is applied automaticall…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

622 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