Question

I have a custom class 'team' and one of its attributes is its 'name.' After each 'team' is created, I add it to a vector teamList.

I would like to implement a function that continuously prompts the user for a team name which is not already taken by a team within the teamList. I have the following code:

while (true) {
    string newString;
    bool flag = true;
    getline(cin, newString);
    for (int i = 0; i < teamList.size(); i++) {
        if (teamList[i].name.compare(newString) == 0) flag = false; 
    }
    if (flag == true) {
        return newString;
    } else {
        cout << "name already taken." << endl;
    }
}

However, this code is really ugly; is there a better way to check? Also, a more general question- faced with an issue of ugly code (like this one), what kinds of steps can I take to find a new, cleaner implementation? Thanks.

Was it helpful?

Solution

I would use std::set, which deals with duplicates for you. As an example, you can see that the class is sorted by the string member, and when three are inserted in main, only two stay because two of the insertions have the same string, so they are treated equal.

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

struct SetThing {
    SetThing(int value, const std::string &value2) : i(value), s(value2){}

    int i;
    std::string s;

    bool operator<(const SetThing &other) const {
        return s < other.s;
    }
};

int main() {
    std::set<SetThing> s;
    s.insert(SetThing(5, "abc"));
    s.insert(SetThing(4, "def"));
    s.insert(SetThing(6, "abc"));
    std::cout << s.size();
}

Now for inserting, you can just reprompt while the second member of the returned pair is false:

do {
    //get input
} while (!teamList.insert(somethingBasedOnInput).second);

OTHER TIPS

define an equality operator in team that can compare a team to a string:

  bool team::operator==(string s) const
  {
    return(s==name);
  }

Then you can use find:

vector<team>::const_iterator itr = find(teamList.begin(), teamList.end(),
                                        newString);

if(itr!=league.end())
  cout << "name already taken" << endl;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top