Ultimabuster
Ultimabuster

Reputation: 75

How can I check if a class object exists in a C++ set?

I am trying to write a piece of code that allows the user to input a certain amount of names, and then checks to see if any objects that contain those names exist in the set. What I want is for the program to take the names entered by the user, loop through the set and see if the name exists in any of the object elements, and then print to the command line whether the name exists or not.

For some reason, it prints "Name does not exist in set" for each element in the set even if the name exists in the set. How can I get this to check properly? Also, how can I get it to only print the "does not exist" message once even if the check fails multiple times before finding (or not finding) a match?

My code so far is:

#include <iostream>
#include <set>
#include <string>
#include <cassert>

using namespace std;

class Name {
   public:
      Name();
      Name(string n);
      bool operator<(Name right)const; 
      string get_name()const;
   private:
      string name;             
};

Name::Name(){}

Name::Name(string n)
{
   name = n;
}

bool Name::operator<(Name right)const
{
      bool result = true;
      return result;
}

string Name::get_name()const
{
      return "Name name is: " + name + "\n";
}

int main(){

set<Name>NamesSet;
NamesSet.insert(Name("Patrick Star"));
NamesSet.insert(Name("Jason"));
NamesSet.insert(Name("Bob Marl"));
NamesSet.insert(Name("Greg"));
set<Name>::iterator pos; 


int numjobs;
string cusname;
cout << "Number of names to enter:" << endl;
cin >> numjobs;
cin.ignore();
if (numjobs != 0 || numjobs > 0) {
   for (int i = 0; i != numjobs; i++)
   {
      cout << endl;
      cout << "Name " << i+1 << ": " << endl;
      getline(cin, cusname);

      for (pos = NamesSet.begin(); pos != NamesSet.end(); pos++) 
      {
         if (NamesSet.count((*pos).get_name()))
         {
            cout << (*pos).get_name() << " exists in set";
            break;
         }
         else 
         {
            cout << "Name does not exist in set";
         }
      }
   }
}

   return 0;
}

Upvotes: 0

Views: 5545

Answers (4)

Hossein
Hossein

Reputation: 25924

You need to change these :

bool Name::operator<(const Name& right)const
{
      return (this->name < right.name);
}

string Name::get_name()const
{
      return name;
}

This would be a working sample :

#include <iostream>
#include <set>
#include <string>
#include <cassert>

using namespace std;

class Name {
   public:
      Name();
      Name(string n);
      bool operator<(const Name& right)const; 
      string get_name()const;
   private:
      string name;             
};

Name::Name(){}

Name::Name(string n)
{
   name = n;
}

bool Name::operator<(const Name& right)const
{
      return (this->name < right.name);
}

string Name::get_name()const
{
      return name;
}

int main()
{

set<Name>NamesSet;
NamesSet.insert(Name("Patrick Star"));
NamesSet.insert(Name("Jason"));
NamesSet.insert(Name("Bob Marl"));
NamesSet.insert(Name("Greg"));
set<Name>::iterator pos; 

string cusname = "Greg";

if ( NamesSet.count(cusname) == 1 )
{
    cout << cusname << " exists in set"<<endl;
}
else 
{
    cout<<"Nanda!";
}

   return 0;
}

http://codepad.org/kg9gtSsX

Upvotes: 1

Chandler
Chandler

Reputation: 97

You need this

bool operator< (const Name& right) {
    return name < right.name;
};

However, in this case, you may directly use the string, instead of Name.

Upvotes: 1

nneonneo
nneonneo

Reputation: 179392

Your Name::operator< is incorrect. It returns true always, which means that the set will always believe two Name objects to compare unequal.

Instead, compare your name strings by returning this->name < right.name, and you should see the right behaviour from your set.

(Incidentally, your operator< should take a const Name & for efficiency's sake).

Upvotes: 3

Surt
Surt

Reputation: 16089

This part of the code is wrong for starters

  for (pos = NamesSet.begin(); pos != NamesSet.end(); pos++) <-------- count does this for you
  {
     if (NamesSet.count((*pos).get_name())) <------ you check the whole set to see if it is in itself
     {
        cout << (*pos).get_name() << " exists in set";
        break;
     }
     else 
     {
        cout << "Name does not exist in set";
     }
  }

This should be better, replace the above with this:

     if (NamesSet.count(cusname))
     {
        cout << cusname << " exists in set";
        break;
     }
     else 
     {
        cout << "Name does not exist in set";
     }

Upvotes: 1

Related Questions