C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

<string> to lowercase
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Zombie
Guest





PostPosted: Wed Aug 18, 2004 6:20 pm    Post subject: <string> to lowercase Reply with quote



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++.moderated. First time posters: Do this! ]
Back to top
Matt Wharton
Guest





PostPosted: Wed Aug 18, 2004 6:45 pm    Post subject: Re: <string> to lowercase Reply with quote



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

-Matt

"Zombie" <natkhatbandar (AT) yahoo (DOT) com> wrote

Quote:
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++.moderated. First time posters: Do this! ]

Back to top
Kai-Uwe Bux
Guest





PostPosted: Wed Aug 18, 2004 6:47 pm    Post subject: Re: <string> to lowercase Reply with quote



Zombie wrote:

Quote:
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.


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++.moderated. First time posters: Do this! ]

Back to top
Xenos
Guest





PostPosted: Thu Aug 19, 2004 11:59 am    Post subject: Re: <string> to lowercase Reply with quote


"Zombie" <natkhatbandar (AT) yahoo (DOT) com> wrote

Quote:
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?

off the top of my head:

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

OR

string to_lowercase(const std::string& s)
{
std::string t;
for (std::string::const_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++.moderated. First time posters: Do this! ]

Back to top
Joe C
Guest





PostPosted: Thu Aug 19, 2004 12:00 pm    Post subject: Re: <string> to lowercase Reply with quote


"Zombie" <natkhatbandar (AT) yahoo (DOT) com> wrote

Quote:
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?


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++.moderated. First time posters: Do this! ]

Back to top
Andre Kostur
Guest





PostPosted: Thu Aug 19, 2004 12:03 pm    Post subject: Re: <string> to lowercase Reply with quote

"Matt Wharton" <noSpam (AT) noSpam (DOT) com> wrote in news:1092853381.442698
@cswreg.cos.agilent.com:

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

Wouldn't you want std::transform ?

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

Back to top
Brian Stone
Guest





PostPosted: Thu Aug 19, 2004 12:16 pm    Post subject: Re: <string> to lowercase Reply with quote

[email]natkhatbandar (AT) yahoo (DOT) com[/email] (Zombie) wrote in message news:<902e612a.0408180133.3b49dfe5 (AT) posting (DOT) google.com>...
Quote:
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.

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(::tolower) );
cout << A << endl; // output: testing!
transform ( A.begin(), A.end(), A.begin(), ptr_fun(::toupper) );
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++.moderated. First time posters: Do this! ]

Back to top
Tommy Andreasen
Guest





PostPosted: Fri Aug 20, 2004 12:23 am    Post subject: Re: <string> to lowercase Reply with quote

Zombie wrote:
Quote:
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.

I usually to it like this:

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

Tommy -

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

Back to top
Thierry Miceli
Guest





PostPosted: Fri Aug 20, 2004 12:26 am    Post subject: Re: <string> to lowercase Reply with quote

Quote:
Hi, what is the correct way of converting contents of a <string> to
lowercase?

Here is one way to do it:

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

int main()
{
std::string str("I WANT THIS IN LOWERCASE.");
std::transform(str.begin(), str.end(), str.begin(), std::tolower);

std::cout << str << std::endl;
return 0;
}

Regards,

Thierry

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

Back to top
Old Wolf
Guest





PostPosted: Fri Aug 20, 2004 12:27 am    Post subject: Re: <string> to lowercase Reply with quote

Kai-Uwe Bux <jkherciueh (AT) gmx (DOT) net> wrote:
Quote:
Zombie wrote:
Hi, what is the correct way of converting contents of a <string> to
lowercase?

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

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

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(*iter);

Quote:
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;
}

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

Back to top
John Dibling
Guest





PostPosted: Fri Aug 20, 2004 12:31 am    Post subject: Re: <string> to lowercase Reply with quote

On 18 Aug 2004 14:20:10 -0400, [email]natkhatbandar (AT) yahoo (DOT) com[/email] (Zombie) wrote:


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


This should do it...

std::string s = "THIS IS A STRING";
transform(s.begin(),s.end(),s.begin(),tolower);


- John

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

Back to top
Peter Koch Larsen
Guest





PostPosted: Fri Aug 20, 2004 12:51 am    Post subject: Re: <string> to lowercase Reply with quote


"Zombie" <natkhatbandar (AT) yahoo (DOT) com> skrev i en meddelelse
news:902e612a.0408180133.3b49dfe5 (AT) posting (DOT) google.com...
Quote:
Hi, what is the correct way of converting contents of a <string> to
lowercase?

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++.moderated. For a "basic" conversion, for_each
and tolower would be okay (perhaps combined with some locale but i am not
familiar with these).

Quote:
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?

Yes - that approach surely seems to cumbersome.

Quote:

Thanks for your time.


Kind regards
Peter


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

Back to top
Kai-Uwe Bux
Guest





PostPosted: Fri Aug 20, 2004 10:10 am    Post subject: Re: <string> to lowercase Reply with quote

Old Wolf wrote:

Quote:
Kai-Uwe Bux <jkherciueh (AT) gmx (DOT) net> wrote:
Zombie wrote:
Hi, what is the correct way of converting contents of a <string> to
lowercase?

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

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

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(*iter);

I was under the impression that std::tolower, being a template, would be
instantiated for the deduced type is a std::string::iterator. 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++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Fri Aug 20, 2004 2:40 pm    Post subject: Re: <string> to lowercase Reply with quote

[email]no.more.spam (AT) stoneentertainment (DOT) com[/email] (Brian Stone) wrote in message
news:<acd67ea1.0408181412.6b38c3ca (AT) posting (DOT) google.com>...

Quote:
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 #include #include #include
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(::tolower) );
cout << A << endl; // output: testing!
transform ( A.begin(), A.end(), A.begin(), ptr_fun(::toupper) );
cout << A << endl; // output: TESTING!
}

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 ::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 objektorientierter Datenverarbeitung
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++.moderated. First time posters: Do this! ]

Back to top
kanze@gabi-soft.fr
Guest





PostPosted: Fri Aug 20, 2004 2:42 pm    Post subject: Re: <string> to lowercase Reply with quote

[email]no.more.spam (AT) stoneentertainment (DOT) com[/email] (Brian Stone) wrote in message
news:<acd67ea1.0408181412.6b38c3ca (AT) posting (DOT) google.com>...
Quote:
natkhatbandar (AT) yahoo (DOT) com (Zombie) wrote in message
news:<902e612a.0408180133.3b49dfe5 (AT) posting (DOT) google.com>...

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?

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 #include #include #include
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(::tolower) );
cout << A << endl; // output: testing!
transform ( A.begin(), A.end(), A.begin(), ptr_fun(::toupper) );
cout << A << endl; // output: TESTING!
}

1. This isn't guaranteed to compile, for at least two reasons. The
obvious one is that you've forgotten to include 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 objektorientierter Datenverarbeitung
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++.moderated. First time posters: Do this! ]

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Goto page 1, 2, 3  Next
Page 1 of 3

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.