10
void main() { std::string str1 = "abracadabra"; std::string str2 = "AbRaCaDaBra"; if (!str1.compare(str2)) { cout << "Compares" } } 

How can I make this work? Bascially make the above case insensitive. Related question I Googled and here

http://msdn.microsoft.com/en-us/library/zkcaxw5y.aspx

there is a case insensitive method String::Compare(str1, str2, Bool). Question is how is that related to the way I am doing.

5
  • Thanks, but there they use boost. My question is is there a way to do the above work without using boost? str1.compare(str2) works and a logical extension to it is to support case insensitive. Is there a simple easy way out? Commented May 29, 2014 at 22:27
  • David your example appears appealing. I might use it. Thanks Commented May 29, 2014 at 22:30
  • 2
    The link you gave is to a .NET function which is emphatically not part of standard C++ and has no relation to it. Commented May 29, 2014 at 22:32
  • Got it, thanks pardon my ignorance Commented May 29, 2014 at 22:52
  • I think that the right way of doing this is to define a trait like in this answer. That allows you to create a map or a set with case insensitive strings without much work. If you just need to compare two strings in one place, you can always use the strcasecmp() function which will also handle the locale properly. Commented Mar 13, 2022 at 19:24

2 Answers 2

26

You can create a predicate function and use it in std::equals to perform the comparison:

bool icompare_pred(unsigned char a, unsigned char b) { return std::tolower(a) == std::tolower(b); } bool icompare(std::string const& a, std::string const& b) { if (a.length()==b.length()) { return std::equal(b.begin(), b.end(), a.begin(), icompare_pred); } else { return false; } } 

Now you can simply do:

if (icompare(str1, str)) { std::cout << "Compares" << std::endl; } 
Sign up to request clarification or add additional context in comments.

8 Comments

This has the advantage that you can set locale and std::tolower respects that ; as mentioned elsewhere you're still out of luck if you try to use this on UTF-8
@0x499602D2: There's a HUGE difference between non-ASCII and non-BMP. Your code works for ASCII, but not for any codepoints above 127. BMP doesn't come into this (though it fails for BMP too)
This isn't a criticism btw, it's not easy to handle UTF-8 properly
Thanks to all I learnt a lot and finally ended up using this:void main() { std::string str1 = "abracadabra"; std::string str2 = "AbRaCaDaBra"; std::transform(str2.begin(), str2.end(), str2.begin(), tolower); if (!str1.compare(str2)) { std::cout << "compares"; } }
I'm not sure this code correctly answers the question. Shouldn't this use std::equal instead of std::lexicographical_compare? std::lexicographical_compare returns true if the first argument is less than the second and requires a predicate with the same semantics.
|
2

Covert both to lower case and then compare them.

Converting to lower:

for(int i = 0; i < str1.size(); i++) { str[i] = tolower(str[i]); } 

Comparing strings:

if (str1.compare(str2) == 0) { ... } 

A zero value indicates that both strings are equal.

EDIT

This can be used to avoid for loop: http://www.cplusplus.com/reference/algorithm/transform/

std::transform(in.begin(),in.end(),std::back_inserter(out),tolower); 

3 Comments

Thanks but I wanted to avoid this and do as we did in stricmp()
well it is trivial to 'revert' to strcmp, since std::string class supports conversion to C-style string via c_str()
int.begin()? shouldn't it be in.begin() ?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.