By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,433 Members | 776 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,433 IT Pros & Developers. It's quick & easy.

case insensitive string::find

P: n/a
Is there some quick C++ way I can do something similar to string::find ,
but case insensitive ?
Jul 22 '05 #1
Share this Question
Share on Google+
5 Replies


P: n/a

"Nils O. Selåsdal" <NO*@Utel.no> wrote in message
news:b_******************@news2.e.nsc.no...
Is there some quick C++ way I can do something similar to string::find ,
but case insensitive ?


You can use the predicate version of std::search

bool ci_equal(char ch1, char ch2)
{
return toupper((unsigned char)ch1) == toupper((unsigned char)ch2);
}

size_t ci_find(const string& str1, const string& str2)
{
string::iterator pos = search(str1. begin ( ), str1. end ( ), str2.
begin ( ), str2. end ( ), ci_equal);
if (pos == str1. end ( ))
return string::npos;
else
return pos - str1. begin ( );
}

Untested code.

John
Jul 22 '05 #2

P: n/a
John Harrison wrote:
"Nils O. Selåsdal" <NO*@Utel.no> wrote in message
news:b_******************@news2.e.nsc.no...
Is there some quick C++ way I can do something similar to string::find ,
but case insensitive ?

You can use the predicate version of std::search

bool ci_equal(char ch1, char ch2)
{
return toupper((unsigned char)ch1) == toupper((unsigned char)ch2);
}

size_t ci_find(const string& str1, const string& str2)
{
string::iterator pos = search(str1. begin ( ), str1. end ( ), str2.
begin ( ), str2. end ( ), ci_equal);
if (pos == str1. end ( ))
return string::npos;
else
return pos - str1. begin ( );
}

Untested code.

Change to string::const_iterator, it seems to work fine.
Thanks.
Jul 22 '05 #3

P: n/a
John Harrison schrieb:
"Nils O. Selåsdal" <NO*@Utel.no> wrote:
Is there some quick C++ way I can do something similar to string::find ,
but case insensitive ?

You can use the predicate version of std::search

bool ci_equal(char ch1, char ch2)
{
return toupper((unsigned char)ch1) == toupper((unsigned char)ch2);
}


Caveat: that predicate will not work reliably for non-English strings.
e.g. in French accents are usually stripped off of capital letters, so
an 'E' can be equivalent (equal modulus case) to either 'e', 'é', 'è',
or 'ê'. In German, the letter 'ß' only exists in lower case, and the
correct capitalisation is "SS", while the reverse conversion is
ambiguous (some "SS" convert to "ss", others to 'ß').

It still doesn't catch all of those issues, but in most cases tolower()
is the better variant in my experience.

While 100% correct case conversions cannot be done in some languages
without knowledge of their spelling rules and exceptions to them, the
'ß' case IMHO shows that signatures like charT toupper( charT ) have
been designed with ignorance (no offence) towards languages where a
1-char-to-1-char conversion is not possible. Wide character support
doesn't alleviate this at all :-(((
Standardised whole-string case conversion functions would be deerly
needed, even if it's left to the implementation or the application to
implement them for a particular locale.

Regards,
Malte
Jul 22 '05 #4

P: n/a
On Tue, 19 Oct 2004 15:03:14 +0200, Malte Starostik wrote:
John Harrison schrieb:
"Nils O. Selåsdal" <NO*@Utel.no> wrote:
Is there some quick C++ way I can do something similar to string::find ,
but case insensitive ?
.... 1-char-to-1-char conversion is not possible. Wide character support
doesn't alleviate this at all :-(((
Standardised whole-string case conversion functions would be deerly
needed, even if it's left to the implementation or the application to
implement them for a particular locale.

Fortunatly for me, I need only care about ascii a-z,A-Z ..
Jul 22 '05 #5

P: n/a
"Nils O. Selåsdal" <NO*@Utel.no> wrote in message news:b_5dd.2715
Is there some quick C++ way I can do something similar to string::find ,
but case insensitive ?


See John's post for an excellent solution.

A more elaborate possibility is to create a new traits class, similar to
std::char_traits<char>, that compares without sensitivity. But now all
string compare operations are case insensitive, so you might find yourself
trying to use std::search to compare with case sensitivity! I haven't tried
myself yet, but seems this should work:

class ichar_traits : public std::char_traits<char> {
public:
static bool eq(char, char);
static bool lt(char, char);
static int compare(const char *, const char *, size_t n);
static const char * find(const char *, size_t n, char);
};

std::basic_string<char, ichar_traits<char> > s1("Hello");
std::basic_string<char, ichar_traits<char> > s2("HELLO");
assert(s1==s2);
assert(s1.find(s2)==0);
Jul 22 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.