Solved

output an object's string value

Posted on 2003-10-26
13
181 Views
Last Modified: 2010-04-02
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;
}  


 
0
Comment
Question by:deekakes
  • 9
  • 4
13 Comments
 
LVL 30

Expert Comment

by:Axter
Comment Utility
What compiler are you using, and what version?
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
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
 

Author Comment

by:deekakes
Comment Utility
Microsoft Visual C++ 6.0
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
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
 
LVL 30

Expert Comment

by:Axter
Comment Utility
Please post the code which contains the transform() code in your implementation.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
>>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
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 

Author Comment

by:deekakes
Comment Utility
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
 
LVL 30

Expert Comment

by:Axter
Comment Utility
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
 
LVL 30

Expert Comment

by:Axter
Comment Utility
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
 
LVL 30

Expert Comment

by:Axter
Comment Utility
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
 

Author Comment

by:deekakes
Comment Utility
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
 

Author Comment

by:deekakes
Comment Utility
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
 
LVL 30

Accepted Solution

by:
Axter earned 80 total points
Comment Utility
>>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

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

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…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.

763 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

7 Experts available now in Live!

Get 1:1 Help Now