Is there a way to compare strings that is case insensitive? I know I can compare them using stricmp, but is there an inbuilt method or technique?
Thanks in advance
HD
Printable View
Is there a way to compare strings that is case insensitive? I know I can compare them using stricmp, but is there an inbuilt method or technique?
Thanks in advance
HD
No, not really. You can use the Traits template argument to create your own basic_string specialization that only does case insensitive comparisons but if you want to do it just for a moment you'll have to use stricmp or memicmp.
OK. Cheers
HD
And you can't simply assign from a case sensitive basic_string to a insensitive basic_string, you'll have to use iterators (src.begin() and back_inserter(target)) and the copy algorithm.
hmm, this is the second time I think STL isn't generic enough
You are looking at it from the wrong angle...Quote:
Originally posted by kedaman
hmm, this is the second time I think STL isn't generic enough
A couple more operators are needed, of course, but you get the idea. Then you just use ci_char instead of char in std::string... you get case insensitive comparisons, but you also conserve case when copying.Code:#define lcase(x) (((x >='A') && (x <= 'Z')) ? x-'A' + 'a' : x)
template<class t=char>
class ci_char {
private:
t m_c;
public:
ci_char& operator =(t c){m_c = c;}
bool operator ==(t& c) { return lcase(m_c)==lcase(c); }
bool operator ==(ci_char& c){ return lcase(m_c)==lcase(c.m_c);}
...
};
Z.
Z: no I meant, strings shouldn't be inherently case sensitive or case insensitive, the comparation should be. Data should be independent of algoritms, even Stepanov had OOP on his mind. Pure abstractuib lies in functional languages.
No operators for the char_traits, only static member functions. Best idea is to take most from char_traits:
That's it.Code:template<typename C>
struct ic_char_traits : public char_traits<C>
{
static int compare(const char_type *s1, const char_type *s2, size_t num) {
int i=0;
for(;i<num;++i) {
if(!eq(*s1, *s2)) {
if(lt(*s1, *s2)) {
return -1;
} else {
return 1;
}
}
}
return 0;
}
static bool eq(const char_type &ch1, const char_type &ch2) {
locale loc;
return tolower(ch1, loc) == tolower(ch2, loc);
}
static bool eq_int_type(const int_type &ch1, const int_type &ch2) {
locale loc;
return tolower((char_type)ch1, loc) == tolower((char_type)ch2, loc);
}
struct eq_pred {
bool operator()(C ch1, C ch2) {
locale loc;
return tolower(ch1, loc) == tolower(ch2, loc);
}
};
static const char_type * find(const char_type *s, size_t num, const char_type &c) {
const char_type *res = search_n(s, s+num, 1, c);
return (res < s+num)?res:NULL;
}
static bool lt(const char_type &ch1, const char_type &ch2) {
locale loc;
return char_traits<char_type>::lt(tolower(ch1, loc), tolower(ch2, loc));
}
};
typedef ci_string basic_string<char, ci_char_traits<char>, allocator<char> >;
typedef ci_wstring basic_string<wchar_t, ci_char_traits<wchar_t>, allocator<wchar_t> >;
typedef ci_tstring basic_string<tchar_t, ci_char_traits<tchar_t>, allocator<tchar_t> >;
tchar_t is an invention of mine, defined equivalent to TCHAR or _TCHAR. But I like the name more.
Keda: you mean the char_traits template parameter should be passed to the comparison function? They probably left that out because template methods of template classes are a very new thing and not supported when the basic_string class was standardized.
When was the first time?
template methods of template classes weren't available when STL was made? That still isn't enough reason to skip genericity, and put static type methods in the classes, you could go with the old function outher, class inner
What would you have done then?
remove all methods from the classes, and go with global template functions and structs with public data all the way
Oh, well...