0

I'm making a text game, and want my options to have a common definer. Which works. But I want std::cin >> choice; to always be lowercase so that an uppercase misspell doesn't matter for the player. Can't find any answers.

cpp file:

std::cout << std::endl << "Choise:";
std::cin >> choice;

if (dLookAround)
{
    std::cout << "ede" << std::endl; //just a test
}

headerfile:

private:
std::string choice;

#define dLookAround \
    (choice == "Look around"\
    || choice == "What do i see?"\
    || choice == "What do i see"\
    || choice == "Explore"\
    || choice == "Scout")

In this state, the code works. But I want cin to read choice in lowercase so that I don't need to write every single word with uppercase and lowercase in the #define all the time.

Azeem
  • 11,148
  • 4
  • 27
  • 40
Wilicious
  • 15
  • 4
  • 2
    https://stackoverflow.com/questions/313970/how-to-convert-stdstring-to-lower-case – Evg Oct 19 '19 at 11:28
  • 1
    Possible duplicate of [How to convert std::string to lower case?](https://stackoverflow.com/questions/313970/how-to-convert-stdstring-to-lower-case) – RHertel Oct 19 '19 at 11:39

2 Answers2

1

You can simply transform the choice to lowercase with std::transform from <algorithm> header and std::tolower from <cctype> header; and. then test it.

For example:

std::transform( choice.begin(), choice.end(), choice.begin(),
                []( auto c ){ return std::tolower( c ); } );

BTW, you should pass the choice to dLookAround to make it more readable in the if statement like this:

if ( dLookAround( choice ) ) { /* ... */ }

Or with better naming convetions like isSelected and choice:

if ( isSelected( choice ) ) { /* ... */ }
Azeem
  • 11,148
  • 4
  • 27
  • 40
  • 1
    It's easier without including , by using `tolower` from the global namespace: `std::transform(choice.begin(), choice.end(), choice.begin(), ::tolower);` – RHertel Oct 19 '19 at 11:51
  • @RHertel: Yes. That could be an alternative too. Thanks for pointing out. – Azeem Oct 19 '19 at 12:09
  • I am such a fool ahaha! The transform didnt work earlier because i defined choice with uppercase letters, so making cin lower letter didnt work because it made the cin to lowercase while choise was uppercase. I switched all the definers to lowercase, and if cin has uppecase, they get transformed to lowercse. So it works now, thanks! :D – Wilicious Oct 19 '19 at 12:21
  • Note that tolower works great on, say, ASCII, but not so good on arbitrary UTF-8 sequences. `"СЧАСТЬЕ "` will not get converted to `"счастье"`. If ASCII is all you need for your use case, you're golden! But if you have to support Unicode, it becomes a bit more of a chore. – Eljay Oct 19 '19 at 14:07
1

I would simply use a case-insensitive comparison, like strcmpi() or equivalent, instead of converting the input, eg:

#define dLookAround ( \
    (strcmpi(choice.c_str(), "Look around") == 0) || \
    (strcmpi(choice.c_str(), "What do i see?") == 0) || \
    (strcmpi(choice.c_str(), "What do i see") == 0) || \
    (strcmpi(choice.c_str(), "Explore") == 0) || \
    (strcmpi(choice.c_str(), "Scout") == 0) \
    )
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • `strcmpi()` is not a standard C function. If it doesn't exist in your library, you can use my `strncmpci()` function I manually wrote here instead: https://stackoverflow.com/questions/5820810/case-insensitive-string-comp-in-c/55293507#55293507 – Gabriel Staples Oct 19 '19 at 18:16