0

I'm fairly new to C++ so forgive me if this is a stupid question, but I've searched and I only found something about std::find which doesn't seem to do what I want (perhaps I'm not using it properly).

As an example, say I have a basic program that can store your gender. I have an if statement that just checks if the user entered "male" or "Male" and then does whatever I want it to do like so:

if(gender == "male" || gender == "Male"){
    // Do stuff
}

I'd like to expand it so a user can enter "m" or "M" as well, and it'll be detected as male. However, I think the if statement would be a bit messy so I'm thinking about sticking the options into a simple array and doing:

if(gender is in maleArray){
    // Do stuff
}

Is this possible? I'm not too bothered about any bad practices involved as this is a learning scenario, although any (useful) criticisms or alternatives are appreciated, as are examples!

Thanks in advance, hope I made it clear enough.

BoBTFish
  • 19,167
  • 3
  • 49
  • 76
whitfin
  • 4,539
  • 6
  • 39
  • 67
  • 4
    `std::find` would do what you want. – Luchian Grigore Feb 26 '13 at 16:47
  • Can you post an example as an answer? I can't seem to get a grasp of it as an if condition. – whitfin Feb 26 '13 at 16:49
  • So would `std::string::find`. – Fred Larson Feb 26 '13 at 16:49
  • You should consider forcing `gender` to lowercase as well maybe for the comparison, so that you don't have redundant cases like `male`, `mAle`, `maLe`, etc. – crush Feb 26 '13 at 16:50
  • @crush How would I go about doing that (in addition to the above)? – whitfin Feb 26 '13 at 16:51
  • When you say `string` are you referring to `std::string` or a `char*` – crush Feb 26 '13 at 16:52
  • Okay, also need to know what type of array of strings you are using. Are you just using something like `std::string[]` or `std::vector` or something else? – crush Feb 26 '13 at 16:56
  • @crush I'd just be doing `string maleArray[]` (I think that's `std::string[]`?). But if it's better to go with vectors, I'm fine with that. – whitfin Feb 26 '13 at 16:58
  • @Zackehh9lives I changed the solution in my answer to use `std::array`. It's more appropriate for the job. – Joseph Mansfield Feb 26 '13 at 17:07
  • @sftrabbit You don't need `std::array` either; just leave it as a braced init list `auto male_synonyms = {...};`. Use `std::begin` instead of `male_synonyms.begin` (and same for `end`). If `gender` is a `string` the rest of the code works as is. – Praetorian Feb 26 '13 at 17:18

2 Answers2

4

The solution you're asking for is:

std::array<std::string, 4> male_synonyms = {"Male", "male", "M", "m"};
auto it = std::find(male_synonyms.begin(), male_synonyms.end(), gender);
if (it != male_synonyms.end()) {
  // ...
}

It uses std::find to see if the user input gender is within the sequence of strings male_synonyms. std::find returns the past-the-end iterator if it is not found, so that's what we check against.

However, I'd prefer this:

std::transform(gender.begin(), gender.end(), gender.begin(), std::tolower);
if (gender == "m" || gender == "male") {
  // ...
}

This will accept case insensitive m and male. So MalE, M, mALE, etc. are also correct.

Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
  • 1
    Vectors are nice because they dynamically expand/contract. You have to be careful though because they can do an awful lot of reallocating of memory as I understand it. – crush Feb 26 '13 at 16:59
  • You might need `static_cast(std::lower)` for the second snippet to compile (if the `tolower` overload from ** is also visible) – Praetorian Feb 26 '13 at 17:00
2

If your concern is the messyness of if statement, you can have a method isMale() which returns a boolean. Then you can use it as if(isMale(gender)).

bool isMale(std::string gender)
{
    if(gender == "male" || 
       gender == "Male" ||
       gender == "M"    ||
       gender == "m"      )
    {
        return true;
    }
    else
    {
        return false;
    }
}

If you don't care about the case, you can convert gender string to all small cases and then compare to "male" and "m".

ycshao
  • 1,768
  • 4
  • 18
  • 32