std::string class, is there any built in lowercase converter?

Started by
16 comments, last by mfawcett 18 years, 8 months ago
Hi im using std::string, and i'm doing a string sort and a string search(by dividing and checking if the string im looking for is >, =, < then the marker). Anyway the problem is when sorting capitals with lower case strings, it puts captials in front of lower case, eg: Hello and hi So I was wondering if the std:string class comes with some kind of toLowerCase function? Thanks
Advertisement
No, it doesn't. The reason is that std::string is locale independent and that different languages (locales) have different conventions regarding such conversions. It is easy to do, though, by running one of the tolower() functions (there are several, which causes some trouble with generic code) over each character. Here is a way for you to do it:

#include <cctype>#include <string>std::string str = "Hello World!";for(int i=0; i<str.size();++i)   str = tolower(str);


It's not the ideal way, but that will do the work. I'm sure somebody will come along shortly to post the transform + locale + functor version [grin]
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Quote:Original post by Fruny
It's not the ideal way, but that will do the work. I'm sure somebody will come along shortly to post the transform + locale + functor version [grin]


Well, here's a halfway-there version:

std::transform(theString.begin(), theString.end(), theString.begin(), tolower);


Pretty much the same thing as Fruny's except you don't have to manually write the for loop yourself. Doesn't use any locale/functor goodness.

EDIT: Now I'll join Fruny in waiting for someone to post the transform + locale + functor version [grin]
hmm on the net, it says tolower() arg is an ascii integer, and returns the lower ascii integer.

does the class have some kind of ascii to string converter?

Thanks
the tolower you are refering to is the C standard library version
look for std::tolower ie, C++ Standard Library
"I am a donut! Ask not how many tris/batch, but rather how many batches/frame!" -- Matthias Wloka & Richard Huddy, (GDC, DirectX 9 Performance)

http://www.silvermace.com/ -- My personal website
Quote:Original post by johnnyBravo
hmm on the net, it says tolower() arg is an ascii integer, and returns the lower ascii integer.

does the class have some kind of ascii to string converter?

The ASCII integer is what you want. Read up on what std::transform does; it operates on an element at a time.
Alternatively, you could use the Boost String Algorithms to do this. :)
Quote:Original post by load_bitmap_file
Quote:Original post by Fruny
It's not the ideal way, but that will do the work. I'm sure somebody will come along shortly to post the transform + locale + functor version [grin]


Well, here's a halfway-there version:

std::transform(theString.begin(), theString.end(), theString.begin(), tolower);


Pretty much the same thing as Fruny's except you don't have to manually write the for loop yourself. Doesn't use any locale/functor goodness.

EDIT: Now I'll join Fruny in waiting for someone to post the transform + locale + functor version [grin]


Erm...

#include<functional>#include<string>std::transform(theString.begin(), theString.end(), theString.begin(), std::bind2nd(&std::tolower, locale("fr_FR")) );std::transform(theString.begin(), theString.end(), theString.begin(), std::bind2nd(&std::tolower, locale("POSIX")) );

?

PS. Indeed, Boost String Algorithms are most excellent
Quote:Original post by load_bitmap_file
EDIT: Now I'll join Fruny in waiting for someone to post the transform + locale + functor version [grin]


#include <boost/bind.hpp> // bind#include <locale>         // tolower#include <algorithm>      // transform#include <string>template < typename ForwardIterator >inline ForwardIteratortolower(ForwardIterator first, ForwardIterator last,		const std::locale& locale_ref = std::locale()) {   using namespace boost;   using namespace std;   typedef typename std::iterator_traits<ForwardIterator>::value_type       value_type;   return transform(first, last, first, 		bind(&std::tolower<value_type>, _1, cref(locale_ref)));}template < typename CharT, typename Traits, typename Alloc >inline std::basic_string<CharT, Traits, Alloc>&tolower(std::basic_string<CharT, Traits, Alloc>& s,		const std::locale& locale_ref = std::locale()) {	   tolower(s.begin(), s.end(), locale_ref);   return s;}
Quote:Original post by MrEvil
Erm...

#include<functional>#include<string>std::transform(theString.begin(), theString.end(), theString.begin(), std::bind2nd(&std::tolower, locale("fr_FR")) );std::transform(theString.begin(), theString.end(), theString.begin(), std::bind2nd(&std::tolower, locale("POSIX")) );

?


Well that shouldn't compile, apart from missing some headers [grin], std::tolower in the header locale is a template function, you need to do an explicit instantiation when giving the address to std::bind2nd

This topic is closed to new replies.

Advertisement