Reputation: 75
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
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;
}
Upvotes: 1
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
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
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