Go Premium for a chance to win a PS4. Enter to Win

x
?
Solved

output an object's string value

Posted on 2003-10-26
13
Medium Priority
?
196 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
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
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
 

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 320 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

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

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

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
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…
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.
Suggested Courses

926 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