<string> to lowercase

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Zombie

    <string> to lowercase

    Hi, what is the correct way of converting contents of a <string> to
    lowercase?
    There are no methods of <string> class to do this so I fallback on
    strlwr().
    But the c_str() method returns a const pointer which cannot be used
    with strlwr() as it does the conversion inplace. So, I use the
    following logic of copying the contents to a dynamically allocated
    char* array and then doing the conversion:

    -----------------------------
    string str = "faLSe";
    char* pc_str = NULL;

    pc_str = new char[str.length() + 1];
    memset(pc_str, 0, sizeof(pc_str)) ;

    strcpy(pc_str, str.c_str());
    strlwr(pc_str);
    // pc_str now contains "false"
    -----------------------------

    Is there any other, less cumbersome way of doing the same?

    Thanks for your time.

    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.m oderated. First time posters: Do this! ]
  • Matt Wharton

    #2
    Re: &lt;string&g t; to lowercase

    You might look at using the 'for_each' algorithm in conjunction with the
    string's iterators and 'tolower'.

    -Matt

    "Zombie" <natkhatbandar@ yahoo.com> wrote in message
    news:902e612a.0 408180133.3b49d fe5@posting.goo gle.com...[color=blue]
    > Hi, what is the correct way of converting contents of a <string> to
    > lowercase?
    > There are no methods of <string> class to do this so I fallback on
    > strlwr().
    > But the c_str() method returns a const pointer which cannot be used
    > with strlwr() as it does the conversion inplace. So, I use the
    > following logic of copying the contents to a dynamically allocated
    > char* array and then doing the conversion:
    >
    > -----------------------------
    > string str = "faLSe";
    > char* pc_str = NULL;
    >
    > pc_str = new char[str.length() + 1];
    > memset(pc_str, 0, sizeof(pc_str)) ;
    >
    > strcpy(pc_str, str.c_str());
    > strlwr(pc_str);
    > // pc_str now contains "false"
    > -----------------------------
    >
    > Is there any other, less cumbersome way of doing the same?
    >
    > Thanks for your time.[/color]



    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
    [ comp.lang.c++.m oderated. First time posters: Do this! ]

    Comment

    • Kai-Uwe Bux

      #3
      Re: &lt;string&g t; to lowercase

      Zombie wrote:
      [color=blue]
      > Hi, what is the correct way of converting contents of a <string> to
      > lowercase?
      > There are no methods of <string> class to do this so I fallback on
      > strlwr().
      > But the c_str() method returns a const pointer which cannot be used
      > with strlwr() as it does the conversion inplace. So, I use the
      > following logic of copying the contents to a dynamically allocated
      > char* array and then doing the conversion:
      >
      > -----------------------------
      > string str = "faLSe";
      > char* pc_str = NULL;
      >
      > pc_str = new char[str.length() + 1];
      > memset(pc_str, 0, sizeof(pc_str)) ;
      >
      > strcpy(pc_str, str.c_str());
      > strlwr(pc_str);
      > // pc_str now contains "false"
      > -----------------------------
      >
      > Is there any other, less cumbersome way of doing the same?
      >
      > Thanks for your time.[/color]


      The following uses the current locale to convert a string to lowercase:

      #include <string>
      #include <iostream>
      #include <locale>

      template < typename Iter >
      void range_tolower ( Iter beg, Iter end ) {
      for( Iter iter = beg; iter != end; ++iter ) {
      *iter = std::tolower( *iter );
      }
      }

      void string_tolower ( std::string & str ) {
      range_tolower( str.begin(), str.end() );
      }

      int main ( void ) {
      std::string test ( "Test" );
      string_tolower( test );
      std::cout << test << std::endl;
      }


      Best

      Kai-Uwe

      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
      [ comp.lang.c++.m oderated. First time posters: Do this! ]

      Comment

      • Ashes

        #4
        Re: &lt;string&g t; to lowercase

        Hi

        You can also use the transform() algorithm:

        #include <string>
        #include <algorithm>

        void ConvertToLowerC ase(std::string & str)
        {
        std::transform( str.begin(),
        str.end(),
        str.begin(),
        tolower);
        // You may need to cast the above line to (int(*)(int))
        // tolower - this works as is on VC 7.1 but may not work on
        // other compilers
        }

        Regards
        Ashley

        Comment

        • Xenos

          #5
          Re: &lt;string&g t; to lowercase


          "Zombie" <natkhatbandar@ yahoo.com> wrote in message
          news:902e612a.0 408180133.3b49d fe5@posting.goo gle.com...[color=blue]
          > Hi, what is the correct way of converting contents of a <string> to
          > lowercase?
          > There are no methods of <string> class to do this so I fallback on
          > strlwr().
          > But the c_str() method returns a const pointer which cannot be used
          > with strlwr() as it does the conversion inplace. So, I use the
          > following logic of copying the contents to a dynamically allocated
          > char* array and then doing the conversion:
          >
          > -----------------------------
          > string str = "faLSe";
          > char* pc_str = NULL;
          >
          > pc_str = new char[str.length() + 1];
          > memset(pc_str, 0, sizeof(pc_str)) ;
          >
          > strcpy(pc_str, str.c_str());
          > strlwr(pc_str);
          > // pc_str now contains "false"
          > -----------------------------
          >
          > Is there any other, less cumbersome way of doing the same?[/color]

          off the top of my head:

          void to_lowercase(st d::string&s)
          {
          for (std::string::i terator i = s.begin(); i != s.end(); ++i)
          *i = tolower(*i);
          }

          OR

          string to_lowercase(co nst std::string& s)
          {
          std::string t;
          for (std::string::c onst_iterator i = s.begin(); i != s.end(); ++i)
          t += tolower(*i);
          return t;
          }


          or you could use a function object with one of the standard library
          templates such as for_each or transform.




          [ See http://www.gotw.ca/resources/clcm.htm for info about ]
          [ comp.lang.c++.m oderated. First time posters: Do this! ]

          Comment

          • Joe C

            #6
            Re: &lt;string&g t; to lowercase


            "Zombie" <natkhatbandar@ yahoo.com> wrote in message
            news:902e612a.0 408180133.3b49d fe5@posting.goo gle.com...[color=blue]
            > Hi, what is the correct way of converting contents of a <string> to
            > lowercase?
            > There are no methods of <string> class to do this so I fallback on
            > strlwr().
            > But the c_str() method returns a const pointer which cannot be used
            > with strlwr() as it does the conversion inplace. So, I use the
            > following logic of copying the contents to a dynamically allocated
            > char* array and then doing the conversion:
            >
            > -----------------------------
            > string str = "faLSe";
            > char* pc_str = NULL;
            >
            > pc_str = new char[str.length() + 1];
            > memset(pc_str, 0, sizeof(pc_str)) ;
            >
            > strcpy(pc_str, str.c_str());
            > strlwr(pc_str);
            > // pc_str now contains "false"
            > -----------------------------
            >
            > Is there any other, less cumbersome way of doing the same?
            >[/color]

            These 2 little functions change the case of strings. Note that these assume
            ASCII and as such are not portable. I've been told that these are the worst
            functions ever...but they work for me...
            if you want it to change the actual string rather than returning a new
            string, just pass a reference to a void function and make the change to the
            charecter of the original string.

            here they are:


            #include <iostream>
            #include <string>

            using namespace std;

            string lcase(string in);
            string ucase(string in);

            int main(){
            string str("A mIxEd CaSe StRiNg 123!@@#");

            cout << str << endl
            << lcase(str) << endl
            << ucase(str) << endl;

            return 0;
            }

            string lcase(string in){
            string stringout;
            for(int i = 0; i < in.size(); ++i)
            if(!(in[i] & 128) && ((in[i] & 95) > 64) && ((in[i] & 31) <= 26))
            stringout += (in[i] | 32); //turn on the lcase bit
            else stringout += in[i]; //character wasn't a letter...dont change
            return stringout;
            }

            string ucase(string in){
            string stringout;
            for(int i = 0; i < in.size(); ++i)
            if(!(in[i] & 128) && ((in[i] & 95) > 64) && ((in[i] & 31) <= 26))
            stringout += (in[i] & (223)); //turn off the lcase bit
            else stringout += in[i]; //character wasn't a letter...dont change
            return stringout;
            }


            [ See http://www.gotw.ca/resources/clcm.htm for info about ]
            [ comp.lang.c++.m oderated. First time posters: Do this! ]

            Comment

            • Andre Kostur

              #7
              Re: &lt;string&g t; to lowercase

              "Matt Wharton" <noSpam@noSpam. com> wrote in news:1092853381 .442698
              @cswreg.cos.agi lent.com:
              [color=blue]
              > You might look at using the 'for_each' algorithm in conjunction with the
              > string's iterators and 'tolower'.[/color]

              Wouldn't you want std::transform ?

              [ See http://www.gotw.ca/resources/clcm.htm for info about ]
              [ comp.lang.c++.m oderated. First time posters: Do this! ]

              Comment

              • Brian Stone

                #8
                Re: &lt;string&g t; to lowercase

                natkhatbandar@y ahoo.com (Zombie) wrote in message news:<902e612a. 0408180133.3b49 dfe5@posting.go ogle.com>...[color=blue]
                > Hi, what is the correct way of converting contents of a <string> to
                > lowercase?
                > There are no methods of <string> class to do this so I fallback on
                > strlwr().
                > But the c_str() method returns a const pointer which cannot be used
                > with strlwr() as it does the conversion inplace. So, I use the
                > following logic of copying the contents to a dynamically allocated
                > char* array and then doing the conversion:
                >
                > -----------------------------
                > string str = "faLSe";
                > char* pc_str = NULL;
                >
                > pc_str = new char[str.length() + 1];
                > memset(pc_str, 0, sizeof(pc_str)) ;
                >
                > strcpy(pc_str, str.c_str());
                > strlwr(pc_str);
                > // pc_str now contains "false"
                > -----------------------------
                >
                > Is there any other, less cumbersome way of doing the same?
                >
                > Thanks for your time.[/color]

                The easiest way I know is to use the transform() function from the
                <algorithm> library. Here's an example of how to apply this to a
                string to convert the case...

                #include <iostream>
                #include <string>
                #include <algorithm>
                #include <functional>
                #include <cctype>

                using namespace std;

                int main ( int argc, char **argv )
                {
                string A = "TeStInG!";

                cout << A << endl; // output: TeStInG!
                transform ( A.begin(), A.end(), A.begin(), ptr_fun(::tolow er) );
                cout << A << endl; // output: testing!
                transform ( A.begin(), A.end(), A.begin(), ptr_fun(::toupp er) );
                cout << A << endl; // output: TESTING!
                }

                -- Brian Stone
                South Dakota School of Mines & Technology
                UAV Team Lead Programmer

                [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                [ comp.lang.c++.m oderated. First time posters: Do this! ]

                Comment

                • Tommy Andreasen

                  #9
                  Re: &lt;string&g t; to lowercase

                  Zombie wrote:[color=blue]
                  > Hi, what is the correct way of converting contents of a <string> to
                  > lowercase?
                  > There are no methods of <string> class to do this so I fallback on
                  > strlwr().
                  > But the c_str() method returns a const pointer which cannot be used
                  > with strlwr() as it does the conversion inplace. So, I use the
                  > following logic of copying the contents to a dynamically allocated
                  > char* array and then doing the conversion:
                  >
                  > -----------------------------
                  > string str = "faLSe";
                  > char* pc_str = NULL;
                  >
                  > pc_str = new char[str.length() + 1];
                  > memset(pc_str, 0, sizeof(pc_str)) ;
                  >
                  > strcpy(pc_str, str.c_str());
                  > strlwr(pc_str);
                  > // pc_str now contains "false"
                  > -----------------------------
                  >
                  > Is there any other, less cumbersome way of doing the same?
                  >
                  > Thanks for your time.[/color]

                  I usually to it like this:

                  std::transform( str.begin(), str.end(), str.begin(),
                  std::ptr_fun(st d::tolower));

                  Tommy -

                  [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                  [ comp.lang.c++.m oderated. First time posters: Do this! ]

                  Comment

                  • Old Wolf

                    #10
                    Re: &lt;string&g t; to lowercase

                    Kai-Uwe Bux <jkherciueh@gmx .net> wrote:[color=blue]
                    > Zombie wrote:[color=green]
                    > > Hi, what is the correct way of converting contents of a <string> to
                    > > lowercase?[/color]
                    >
                    > The following uses the current locale to convert a string to lowercase:
                    >
                    > #include <string>
                    > #include <iostream>
                    > #include <locale>
                    >
                    > template < typename Iter >
                    > void range_tolower ( Iter beg, Iter end ) {
                    > for( Iter iter = beg; iter != end; ++iter ) {
                    > *iter = std::tolower( *iter );
                    > }
                    > }[/color]

                    Unfortunately, std::tolower requires an argument in the range
                    0...UCHAR_MAX. So you can go:

                    *iter = std::tolower( (unsigned char)*iter );

                    and hope that it gets converted back to char properly afterwards, or:

                    if (*iter >= 0 && *iter <= UCHAR_MAX)
                    *iter = std::tolower(*i ter);
                    [color=blue]
                    > void string_tolower ( std::string & str ) {
                    > range_tolower( str.begin(), str.end() );
                    > }
                    >
                    > int main ( void ) {
                    > std::string test ( "Test" );
                    > string_tolower( test );
                    > std::cout << test << std::endl;
                    > }[/color]

                    [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                    [ comp.lang.c++.m oderated. First time posters: Do this! ]

                    Comment

                    • Peter Koch Larsen

                      #11
                      Re: &lt;string&g t; to lowercase


                      "Zombie" <natkhatbandar@ yahoo.com> skrev i en meddelelse
                      news:902e612a.0 408180133.3b49d fe5@posting.goo gle.com...[color=blue]
                      > Hi, what is the correct way of converting contents of a <string> to
                      > lowercase?[/color]

                      Well... this is actually a rather complicated question. For an explanation
                      as to why, take a look at the thread "Case insensitive comparison of
                      std::strings" in comp.lang.c++.m oderated. For a "basic" conversion, for_each
                      and tolower would be okay (perhaps combined with some locale but i am not
                      familiar with these).
                      [color=blue]
                      > There are no methods of <string> class to do this so I fallback on
                      > strlwr().
                      > But the c_str() method returns a const pointer which cannot be used
                      > with strlwr() as it does the conversion inplace. So, I use the
                      > following logic of copying the contents to a dynamically allocated
                      > char* array and then doing the conversion:
                      >
                      > -----------------------------
                      > string str = "faLSe";
                      > char* pc_str = NULL;
                      >
                      > pc_str = new char[str.length() + 1];
                      > memset(pc_str, 0, sizeof(pc_str)) ;
                      >
                      > strcpy(pc_str, str.c_str());
                      > strlwr(pc_str);
                      > // pc_str now contains "false"
                      > -----------------------------
                      >
                      > Is there any other, less cumbersome way of doing the same?[/color]

                      Yes - that approach surely seems to cumbersome.
                      [color=blue]
                      >
                      > Thanks for your time.[/color]


                      Kind regards
                      Peter


                      [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                      [ comp.lang.c++.m oderated. First time posters: Do this! ]

                      Comment

                      • Kai-Uwe Bux

                        #12
                        Re: &lt;string&g t; to lowercase

                        Old Wolf wrote:
                        [color=blue]
                        > Kai-Uwe Bux <jkherciueh@gmx .net> wrote:[color=green]
                        >> Zombie wrote:[color=darkred]
                        >> > Hi, what is the correct way of converting contents of a <string> to
                        >> > lowercase?[/color]
                        >>
                        >> The following uses the current locale to convert a string to lowercase:
                        >>
                        >> #include <string>
                        >> #include <iostream>
                        >> #include <locale>
                        >>
                        >> template < typename Iter >
                        >> void range_tolower ( Iter beg, Iter end ) {
                        >> for( Iter iter = beg; iter != end; ++iter ) {
                        >> *iter = std::tolower( *iter );
                        >> }
                        >> }[/color]
                        >
                        > Unfortunately, std::tolower requires an argument in the range
                        > 0...UCHAR_MAX. So you can go:
                        >
                        > *iter = std::tolower( (unsigned char)*iter );
                        >
                        > and hope that it gets converted back to char properly afterwards, or:
                        >
                        > if (*iter >= 0 && *iter <= UCHAR_MAX)
                        > *iter = std::tolower(*i ter);[/color]

                        I was under the impression that std::tolower, being a template, would be
                        instantiated for the deduced type <char> when the argument *iter where iter
                        is a std::string::it erator. Now, if it is a template, why should it be
                        restricted to 0..UCHAR_MAX, effectively forcing the type to be unsigned
                        char? That does not seem to make any sense -- of course, this does not
                        imply it isn't so. In any case, I looked up tolower in the standard and did
                        not see any hint at UCHAR_MAX. Probably, I was looking at the wrong
                        section. Could you point me to the source?


                        Best

                        Kai-Uwe Bux

                        [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                        [ comp.lang.c++.m oderated. First time posters: Do this! ]

                        Comment

                        • kanze@gabi-soft.fr

                          #13
                          Re: &lt;string&g t; to lowercase

                          no.more.spam@st oneentertainmen t.com (Brian Stone) wrote in message
                          news:<acd67ea1. 0408181412.6b38 c3ca@posting.go ogle.com>...
                          [color=blue]
                          > The easiest way I know is to use the transform() function from the
                          > <algorithm> library. Here's an example of how to apply this to a
                          > string to convert the case...[/color]
                          [color=blue]
                          > #include <iostream>
                          > #include <string>
                          > #include <algorithm>
                          > #include <functional>
                          > #include <cctype>[/color]
                          [color=blue]
                          > using namespace std;[/color]
                          [color=blue]
                          > int main ( int argc, char **argv )
                          > {
                          > string A = "TeStInG!";[/color]
                          [color=blue]
                          > cout << A << endl; // output: TeStInG!
                          > transform ( A.begin(), A.end(), A.begin(), ptr_fun(::tolow er) );
                          > cout << A << endl; // output: testing!
                          > transform ( A.begin(), A.end(), A.begin(), ptr_fun(::toupp er) );
                          > cout << A << endl; // output: TESTING!
                          > }[/color]

                          Is it just me, or what? There have been a number of postings suggesting
                          this, either with or without the call to ptr_fun. Now, it has some
                          obvious and well known problems when it encounters a character encoding
                          that is negative, and toupper( 'ß' ) doesn't (and cannot) work at all,
                          but I can understand anglocentric programmers missing this in a quick
                          response. On the other hand, I have been unable to find a compiler where
                          this even compiles, in any of the suggested variants, on any system: it
                          fails to compile (with or without the ptr_fun) with g++ (3.4.0), Sun CC
                          (5.1) and VC++ (6.0).

                          In fact, the only variant which compiled (and that got a warning from
                          Sun CC) is yours, with ::tolower and ::toupper. And you are playing on a
                          bug in practically every implementation of <cctype>, which exposes
                          ::tolower and ::toupper (rather than only having them available in
                          std::, as the standard requires).

                          As far as I know (and ignoring the issues of passing an out of bounds
                          value to the functions), the correct way to write the call to transform
                          is something like:

                          std::transform( str.begin(), str.end(),
                          str.begin(),
                          std::ptr_fun( (int (*)( int ))std::tolower ) ) ;

                          Even better would be something like:

                          std::transform(
                          str.begin(), str.end(),
                          str.begin(),
                          boost::bind(
                          std::ptr_fun(
                          (char (*)( char, std::locale const& ))std::tolower ),
                          _1,
                          std::locale() ) ) ;

                          (Some of the Boost experts should verify this. I still have enough older
                          compilers to support that I can't actively use Boost, as much as it
                          would facilitate my code.)

                          This should at least give defined behavior in every case, even if it
                          gives the wrong results sometimes.

                          Of course, the original poster asked for something that wasn't
                          awkward:-).

                          --
                          James Kanze GABI Software http://www.gabi-soft.fr
                          Conseils en informatique orientée objet/
                          Beratung in objektorientier ter Datenverarbeitu ng
                          9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                          [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                          [ comp.lang.c++.m oderated. First time posters: Do this! ]

                          Comment

                          • kanze@gabi-soft.fr

                            #14
                            Re: &lt;string&g t; to lowercase

                            no.more.spam@st oneentertainmen t.com (Brian Stone) wrote in message
                            news:<acd67ea1. 0408181412.6b38 c3ca@posting.go ogle.com>...[color=blue]
                            > natkhatbandar@y ahoo.com (Zombie) wrote in message
                            > news:<902e612a. 0408180133.3b49 dfe5@posting.go ogle.com>...[/color]
                            [color=blue][color=green]
                            > > Hi, what is the correct way of converting contents of a <string> to
                            > > lowercase?
                            > > There are no methods of <string> class to do this so I fallback on
                            > > strlwr().
                            > > But the c_str() method returns a const pointer which cannot be used
                            > > with strlwr() as it does the conversion inplace. So, I use the
                            > > following logic of copying the contents to a dynamically allocated
                            > > char* array and then doing the conversion:[/color][/color]
                            [color=blue][color=green]
                            > > -----------------------------
                            > > string str = "faLSe";
                            > > char* pc_str = NULL;[/color][/color]
                            [color=blue][color=green]
                            > > pc_str = new char[str.length() + 1];
                            > > memset(pc_str, 0, sizeof(pc_str)) ;[/color][/color]
                            [color=blue][color=green]
                            > > strcpy(pc_str, str.c_str());
                            > > strlwr(pc_str);
                            > > // pc_str now contains "false"
                            > > -----------------------------[/color][/color]
                            [color=blue][color=green]
                            > > Is there any other, less cumbersome way of doing the same?[/color][/color]
                            [color=blue]
                            > The easiest way I know is to use the transform() function from the
                            > <algorithm> library. Here's an example of how to apply this to a
                            > string to convert the case...[/color]
                            [color=blue]
                            > #include <iostream>
                            > #include <string>
                            > #include <algorithm>
                            > #include <functional>
                            > #include <cctype>[/color]
                            [color=blue]
                            > using namespace std;[/color]
                            [color=blue]
                            > int main ( int argc, char **argv )
                            > {
                            > string A = "TeStInG!";[/color]
                            [color=blue]
                            > cout << A << endl; // output: TeStInG!
                            > transform ( A.begin(), A.end(), A.begin(), ptr_fun(::tolow er) );
                            > cout << A << endl; // output: testing!
                            > transform ( A.begin(), A.end(), A.begin(), ptr_fun(::toupp er) );
                            > cout << A << endl; // output: TESTING!
                            > }[/color]

                            1. This isn't guaranteed to compile, for at least two reasons. The
                            obvious one is that you've forgotten to include <ostream>. The less
                            obvious one is that any C++ header may include any other C++
                            headers; if <iostream> includes <locale> (actually
                            quite likely, since often <iostream> just includes everything in the
                            iostream section of the library, and both basic_ios and
                            basic_streambuf need <locale>), then the call to ptr_fun will be
                            abiguous.

                            Formally, in fact, I think that the standard guarantees that it
                            won't compile, since there shouldn't be a tolower nor a toupper in
                            global namespace. (But I could be wrong about this. I don't really
                            understand the interactions between "using namespace" and the ::
                            specifier.) In practice, however, I don't know of a single
                            implementation which is conformant in this regard.

                            2. If it compiles, and uses the tolower in <cctype>, then you have
                            undefined behavior, at least if plain char is signed (as it is on
                            most systems). Passing a negative value to the tolower function in
                            <cctype> is undefined behavior.

                            --
                            James Kanze GABI Software http://www.gabi-soft.fr
                            Conseils en informatique orientée objet/
                            Beratung in objektorientier ter Datenverarbeitu ng
                            9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                            [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                            [ comp.lang.c++.m oderated. First time posters: Do this! ]

                            Comment

                            • kanze@gabi-soft.fr

                              #15
                              Re: &lt;string&g t; to lowercase

                              oldwolf@inspire .net.nz (Old Wolf) wrote in message
                              news:<843a4f78. 0408181512.5858 b4d8@posting.go ogle.com>...
                              [color=blue]
                              > Kai-Uwe Bux <jkherciueh@gmx .net> wrote:[color=green]
                              > > Zombie wrote:[color=darkred]
                              > > > Hi, what is the correct way of converting contents of a <string>
                              > > > to lowercase?[/color][/color][/color]
                              [color=blue][color=green]
                              > > The following uses the current locale to convert a string to
                              > > lowercase:[/color][/color]
                              [color=blue][color=green]
                              > > #include <string>
                              > > #include <iostream>
                              > > #include <locale>[/color][/color]
                              [color=blue][color=green]
                              > > template < typename Iter >
                              > > void range_tolower ( Iter beg, Iter end ) {
                              > > for( Iter iter = beg; iter != end; ++iter ) {
                              > > *iter = std::tolower( *iter );
                              > > }
                              > > }[/color][/color]
                              [color=blue]
                              > Unfortunately, std::tolower requires an argument in the range
                              > 0...UCHAR_MAX.[/color]

                              No, it takes a second parameter, a std::locale. E.g.:

                              *iter = std::tolower( *iter, std::locale() ) ;

                              At least in a conforming implementation (see below).
                              [color=blue]
                              > So you can go:[/color]
                              [color=blue]
                              > *iter = std::tolower( (unsigned char)*iter );[/color]

                              This works on a conforming implementation as well, as long as you
                              include <clocale> rather than <locale> or <locale.h>. Conforming
                              implementations are still pretty rare, however, and I've found that
                              leaving the std:: off and including <locale.h> seems to be about the
                              only thing that works portably.

                              And of course, since in this case, you are using the C version of
                              tolower, you have to ensure that the input is an unsigned char. And, as
                              you say, hope that the results don't get mangled when you reconvert back
                              to char -- realistically, the amount of code that mangling them would
                              break (even though the standard allows it) is so large that no
                              implementation would dare...

                              Finally, of course, none of the solutions really work, because there is
                              no one to one mapping of upper case characters to lower case characters.
                              [color=blue]
                              > and hope that it gets converted back to char properly afterwards, or:[/color]
                              [color=blue]
                              > if (*iter >= 0 && *iter <= UCHAR_MAX)
                              > *iter = std::tolower(*i ter);[/color]

                              Actually, the only cases such a mapping can make sense is when you are
                              using pure ASCII, and have no accented characters. So:

                              assert( *iter >= 0 && *iter <= 127 ) ;

                              (assuming ASCII, obviously -- this isn't really portable).

                              --
                              James Kanze GABI Software http://www.gabi-soft.fr
                              Conseils en informatique orientée objet/
                              Beratung in objektorientier ter Datenverarbeitu ng
                              9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

                              [ See http://www.gotw.ca/resources/clcm.htm for info about ]
                              [ comp.lang.c++.m oderated. First time posters: Do this! ]

                              Comment

                              Working...