Home > Back-end >  How to display the country capital even if the input is case insensitive c
How to display the country capital even if the input is case insensitive c

Time:05-02

I've working on this code for quite a while and I can't find how to make this case insensitive

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int findCountry(string arr[], int len, string seek)
{
    for (int i = 0; i < len;   i)
    {
        if (arr[i] == seek) return i;
    }
    return -1;
}

int main(){
    string countries[5]={"Brunei", "Cambodia", "East Timor", "Indonesia", "Laos"};
    string capitals[5]={"Bandar Seri Begawan", "Phnom Penh", "Dili", "Jakarta", "Vientiane"};
        
    string country;
    
    cout << "Country: ";
    cin >> country;
    
    int index = findCountry(countries,5,country);
     if (index >= 0)
        cout << "Capital: " << capitals[index];
    else
        cout << country << " is not a South East Asian Country";
    
    return 0;
}

OUTPUT

Country: bRunEi
bRunEi is not a South East Asian Country

Expected OUTPUT

Country: bRunEi
Capital: Bandar Seri Begawan

I was instructed to use cstring header but this is the only thing I can guess, any help will be appreciated ps: sorry for bad english

CodePudding user response:

Regarding the case insensitive comparison:

You can use the function below to compare 2 strings ignoring the case. You can call it instead of using (arr[i] == seek) to compare strings.

#include <string>
#include <cctype>
bool IsEqualStringsCaseInsensitive(std::string const & s1, std::string const & s2)
{
    int len1 = s1.length();
    int len2 = s2.length();
    if (len1 != len2) {
        return false;
    }
    for (int i = 0; i < len1;   i) {
        if (std::tolower(s1[i]) != std::tolower(s2[i]) {
            return false;
        }
    }
    return true;
}

A few additional notes about your code:

  1. In general it's better to use std::vector<std::string> const & arr instead of old style C arrays (string arr[]).
  2. Better to avoid using namespace std - see here Why is "using namespace std;" considered bad practice?.
  3. You can pass seek by const& to avoid copy.

CodePudding user response:

There are a few points of improvements that can simplify your code.

Firstly if you use a standard container for your countries.

std::vector<std::string> countries = {"Brunei", "Cambodia", "East Timor", "Indonesia", "Laos"};

For having case insensitive input you transform using https://en.cppreference.com/w/cpp/string/byte/tolower or its sibling toupper.

std::tolower is in the <cctype> header, but I'd supppose that is a part of <cstring>.

The reference contains a usage example that covers you case.

std::string str_tolower(std::string s) {
    std::transform(s.begin(), s.end(), s.begin(), 
                [](unsigned char c){ return std::tolower(c); }
                  );
    return s;
}

std::transform is in the header, you should have a look in there for many simple algorithms, that allows you to describe your code in a simpler way than using a regular for-loop like you are doing in findCountry. Look at the algoritm std::find, for instance.

The expression [](unsigned char c){ ... } is a lambda expression, extremely useful combined with the algorithms. https://en.cppreference.com/w/cpp/language/lambda

  •  Tags:  
  • c
  • Related