case insensitive string::find

Discussion in 'C++' started by =?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=, Oct 19, 2004.

  1. Is there some quick C++ way I can do something similar to string::find ,
    but case insensitive ?
    =?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=, Oct 19, 2004
    #1
    1. Advertising

  2. "Nils O. Selåsdal" <> wrote in message
    news:b_5dd.2715$...
    > 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
    John Harrison, Oct 19, 2004
    #2
    1. Advertising

  3. John Harrison wrote:
    > "Nils O. Selåsdal" <> wrote in message
    > news:b_5dd.2715$...
    >
    >>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.
    =?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=, Oct 19, 2004
    #3
  4. John Harrison schrieb:

    > "Nils O. Selåsdal" <> 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
    Malte Starostik, Oct 19, 2004
    #4
  5. On Tue, 19 Oct 2004 15:03:14 +0200, Malte Starostik wrote:

    > John Harrison schrieb:
    >
    >> "Nils O. Selåsdal" <> 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 ..
    =?iso-8859-1?q?Nils_O=2E_Sel=E5sdal?=, Oct 19, 2004
    #5
  6. =?ISO-8859-1?Q?=22Nils_O=2E_Sel=E5sdal=22?=

    Siemel Naran Guest

    "Nils O. Selåsdal" <> 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);
    Siemel Naran, Oct 20, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Tee
    Replies:
    3
    Views:
    7,793
    Herfried K. Wagner [MVP]
    Jun 23, 2004
  2. Johny
    Replies:
    11
    Views:
    681
    Steven D'Aprano
    Feb 8, 2007
  3. Replies:
    1
    Views:
    2,475
    Mark P
    Apr 6, 2007
  4. Prabh
    Replies:
    1
    Views:
    98
    Jürgen Exner
    Feb 19, 2004
  5. Xah Lee
    Replies:
    4
    Views:
    955
Loading...

Share This Page