Solved

output an object's string value

Posted on 2003-10-26
13
184 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
ID: 9624087
What compiler are you using, and what version?
0
 
LVL 30

Expert Comment

by:Axter
ID: 9624093
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
ID: 9624096
Microsoft Visual C++ 6.0
0
 
LVL 30

Expert Comment

by:Axter
ID: 9624126
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
ID: 9624129
Please post the code which contains the transform() code in your implementation.
0
 
LVL 30

Expert Comment

by:Axter
ID: 9624149
>>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
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.

 

Author Comment

by:deekakes
ID: 9624222
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
ID: 9624317
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
ID: 9624358
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
ID: 9624361
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
ID: 9626191
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
ID: 9626991
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
ID: 9631273
>>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

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

Suggested Solutions

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…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
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.
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.

920 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

11 Experts available now in Live!

Get 1:1 Help Now