tags:

views:

8343

answers:

5

Hi,

I want to convert an STL String to lowercase. I am aware of the function tolower() however in the past I have had issues with this function and it is hardly ideal anyway as use with a string would require iterating through each character.

Is there an alternative which works 100% of the time?

+24  A: 

There is a Boost string algorithm for this:

#include <boost/algorithm/string.hpp>    

std::string str = "HELLO, WORLD!";
boost::to_lower(str);
Rob
Agreed; this is the best way to convert a string to lowercase. The documentation for to_lower is here: http://www.boost.org/doc/libs/1_37_0/doc/html/boost/algorithm/to_lower.html
MattyT
While that's great if you have/use boost, what about for those of us that don't/can't?
warren
One of the great things about boost is the liberal license. It basically says "Do whatever you want, just leave the copyright notice." So you can always look to see what they did, or just pull that header file out of the distribution.
KeithB
@warren: If you don't then do. If you can't then find a way you can. There are only two valid reasons not to use Boost: 1) Your target platform is so minimal every extra byte of binary code counts (even then some parts of Boost could possibly be used). 2) You're a masochist.
Andreas Magnusson
There is a problem with this, should read std::string strSomeString = "Hello World";
Konrad
+22  A: 

From http://notfaq.wordpress.com/2007/08/04/cc-convert-string-to-upperlower-case/:

#include <algorithm>
#include <string> 

std::string data = “Abc”; 
std::transform(data.begin(), data.end(), data.begin(), ::tolower);

You're really not going to get away with not iterating through each character. There's no way to know whether the character is lowercase or uppercase otherwise.

If you really hate tolower(), here's an alternative:

char easytolower(char in){
  if(in<='Z' && in>='A')
    return in-('Z'-'z');
  return in;
} 

std::transform(data.begin(), data.end(), data.begin(), easytolower);
Stefan Mai
Problem is that you are still using toupper there
Konrad
I've changed it.
Stefan Mai
That is amazing, ive always wondered what the best way to do it.I had no idea to use std::transform.:)
UberJumper
uberjumper:There's actually a whole lot of overhead associated with the STL calls, especially for small"ish" strings. Solutions using a for loop and tolower are probably much faster.
Stefan Mai
+7  A: 

You may also want to use the C++ locale support for this. You gain genericity.

#include <functional>
#include <locale>

std::string a = "ABC";

std::transform(a.begin(), a.end(), a.begin(), 
    std::bind2nd(std::ptr_fun(&std::tolower<char>), std::locale("")));

If you have a range of writable characters, you can also do

std::use_facet< std::ctype<char> >(std::locale("")).tolower(&a[0], &a[0] + a.size());

locale("") will construct a locale object representing your preferred locale.

I recommend reading Stroustrup's Appendix D: Locales, which is freely available, and is a great insight into locales in C++.

Johannes Schaub - litb
+6  A: 

Note: tolower() doesn't work 100% of the time.

Lowercase/uppercase operations only apply to characters, and std::string is essentially an array of bytes, not characters. Plain tolower is nice for ASCII string, but it will not lowercase a latin-1 or utf-8 string correctly. You must know string's encoding and probably decode it before you can lowercase its characters.

Constantin
A: 

You can't use std::bind2nd(std::ptr_fun(&std::tolower), std::locale()). Use boost::bind(&std::tolower, _1, std::locale()) instead.

Kirill Lykov