output an object's string value

Hello experts:
Question 1:  I have an object that contains a string value
                  and I am having trouble outputting it properly.
                                    (Please see code below.)
Question 2:  Is there a way to use tolower in one of my functions before I sort the list? I tried to use the following in the main program before sort():
                   transform(member_list.begin(),  member_list.end(), member_list.begin(), tolower);
                   but the compiler says:
No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

This is the input:

Henry J Jones   1967   paid
William Shakespeare     1930   paid
John L Smith     1961 paid
Tina Tucker  1999 paid
Jay Bird  2002 not paid
Julia B. Little 2000 not paid

This is the ouput:

Sorted Member List:

Jay   Bird 2002 paid
 Henry J Jones 1967 paid
 not paid Julia B. Little
 paid John L Smith 1961
 William   Shakespeare 1930 paid
 paid Tina Tucker 1999 paid
 2000 not paid  
---------------------------------------------------------
//file name: club_member.cpp

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

using namespace std;

class ClubMember
{
      public:
            ClubMember();
            ClubMember(string a_first_name, string a_middle_init, string a_last_name,
                              string a_membership_yr, string a_dues_status);
            
            string get_last_first_name() const;
            string get_first_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;
            string dues_status;
};

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);
      
      member_list.sort();
      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 cm;
      
      while (!infile.eof())
      {
            infile >> cm;
            member_list.push_back(cm);
      }
}

ClubMember::ClubMember() { }

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

string ClubMember::get_last_first_name() const
{
      string last_first;

      last_first = last_name + first_name;
      return last_first;
}

string ClubMember::get_first_last_name() const
{
      string first_last;
      
      first_last = first_name + last_name  ;
      return first_last;
}

int ClubMember::operator<(ClubMember& a_member)
{
      return last_name < a_member.last_name ||
               (last_name == a_member.last_name &&
                first_name < a_member.first_name);
}

int ClubMember::operator>(ClubMember& a_member)
{
      return last_name > a_member.last_name ||
               (last_name == a_member.last_name &&
                first_name > a_member.first_name);
}
            
istream& operator>>(istream& infile, ClubMember& a_member)
{
      infile >> a_member.first_name >> a_member.middle_init
                >> a_member.last_name;
      
      if(isdigit(a_member.last_name[0]))
      {
            a_member.membership_yr = a_member.last_name;
            a_member.last_name = a_member.middle_init;
            a_member.middle_init = " ";
      }
      else
      {
            infile >> a_member.membership_yr >> a_member.dues_status;
      }
      return infile;
}
      
ostream& operator<<(ostream& outfile, ClubMember& a_member)
{
      outfile << a_member.first_name << " " << a_member.middle_init
              << " " << a_member.last_name << " " << a_member.membership_yr
                  << " " << a_member.dues_status << endl;

      cout << a_member.first_name << " " << a_member.middle_init
           << " " << a_member.last_name << " " << a_member.membership_yr
             << " " << a_member.dues_status << endl << endl;
                  
      return outfile;
}  


 
deekakesAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AxterCommented:
What compiler are you using, and what version?
0
AxterCommented:
Here's a method that is portable:

#include < locale >
#include < algorithm >
#include < functional >
#include < string >

template < typename T >
    T to_lower(T Src, std::locale *Loc)
{
    return std::tolower(Src, *Loc);
}

template < class T >
    void make_lower(T &Src, const char *Lang   = "english")
{
    static T::value_type (*pFunc)(T::value_type, std::locale*) = to_lower < T::value_type >;
    std::locale locE(Lang);
    std::transform(Src.begin(),Src.end(),Src.begin(),std::bind2nd(std::ptr_fun(pFunc), &locE));
}
0
deekakesAuthor Commented:
Microsoft Visual C++ 6.0
0
Cloud Class® Course: C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

AxterCommented:
The following code compiles and runs with no errors on VC++ 6.0

#include <cstdlib>
#include <string>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <list>
#include <algorithm>
using namespace std;

int main(int argc, char* argv[])
{
      string member_list = "Bob Dole";
      transform(member_list.begin(),  member_list.end(), member_list.begin(), tolower);
      
      cout << member_list << endl;
      
      system("pause");
      return 0;
}
0
AxterCommented:
Please post the code which contains the transform() code in your implementation.
0
AxterCommented:
>>Question 1:  I have an object that contains a string value
>>                 and I am having trouble outputting it properly.

More then likely the problem is with the sort() logic, and not with the display logic.

Please post the code you use for sorting.
0
deekakesAuthor Commented:
I was wondering.... should I sort and/or transform in the fill_list() function?

Anyway, here's what I tried to do in main:

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);
      transform(member_list.begin(), member_list.end(),
                   member_list.begin(), tolower);
      member_list.sort();
      print_list(member_list, fout, "Sorted Member List:\n");
      
      fin.close();
      fout.close();
      return 0;
}
0
AxterCommented:
Please post your member function int operator<(ClubMember&);

You should sort after the fill_list function.
You might have something wrong with the operator<(ClubMember&) function.

Since member_list is a list, and not a string, you can't use tolower with it.
0
AxterCommented:
You can use the make_lower_list function listed below, to make lower case all the strings in your list.

#include < locale >
#include < algorithm >
#include < functional >
#include < string >

template < typename T >
    T to_lower(T Src, std::locale *Loc)
{
    return std::tolower(Src, *Loc);
}

template < typename T >
    T to_lower_list(T Src, std::locale *Loc)
{
    static T::value_type (*pFunc)(T::value_type, std::locale*) = to_lower < T::value_type >;
    std::transform(Src.begin(),Src.end(),Src.begin(),std::bind2nd(std::ptr_fun(pFunc),Loc));
    return Src;
}

template < class T >
    void make_lower_list(T &Src, const char *Lang   = "english")
{
    static T::value_type (*pFunc)(T::value_type, std::locale*) = to_lower_list < T::value_type >;
    std::locale locE(Lang);
    std::transform(Src.begin(),Src.end(),Src.begin(),std::bind2nd(std::ptr_fun(pFunc), &locE));
}
0
AxterCommented:
Here's a full example code:

#include <cstdlib>
#include < iostream >
#include < locale >
#include < algorithm >
#include < functional >
#include < string >
#include < list >
using namespace std;

template < typename T >
    T to_lower(T Src, std::locale *Loc)
{
    return std::tolower(Src, *Loc);
}

template < typename T >
    T to_lower_list(T Src, std::locale *Loc)
{
    static T::value_type (*pFunc)(T::value_type, std::locale*) = to_lower < T::value_type >;
    std::transform(Src.begin(),Src.end(),Src.begin(),std::bind2nd(std::ptr_fun(pFunc),Loc));
    return Src;
}

template < class T >
    void make_lower_list(T &Src, const char *Lang   = "english")
{
    static T::value_type (*pFunc)(T::value_type, std::locale*) = to_lower_list < T::value_type >;
    std::locale locE(Lang);
    std::transform(Src.begin(),Src.end(),Src.begin(),std::bind2nd(std::ptr_fun(pFunc), &locE));
}



int main(int argc, char* argv[])
{
      std::list<string> member_list;
      member_list.push_back("Tom");
      member_list.push_back("Joe");
      member_list.push_back("Bob");
      member_list.push_back("Jill");
      make_lower_list(member_list);
      member_list.sort();

      for(std::list<string>::iterator i = member_list.begin();i != member_list.end();++i)
      {
            cout << *i << endl;
      }
      
      system("pause");
      return 0;
}

0
deekakesAuthor Commented:
Thanks for the code. Could you give me any clues why the dues_status attribute doesn't output correctly. (See question 1 in my original question.  I also listed the ouput).
0
deekakesAuthor Commented:
I forgot to include this function in my last comment (it's also in the original code I posted).  I just need to sort by last name.

int ClubMember::operator<(ClubMember& a_member)
{
     return last_name < a_member.last_name ||
             (last_name == a_member.last_name &&
              first_name < a_member.first_name);
}
0
AxterCommented:
>>Could you give me any clues why the dues_status attribute doesn't output correctly. (See question 1 in my original question.  I also listed the ouput).

This problem is occuring because of the logic in the operator>>() function.

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

This logic only works if all members have a middle name.  If you try entering a member with no middle name, it will through off everything.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.