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