|
Boost : |
From: Srivatsan Raghavan (vraghavan_at_[hidden])
Date: 2002-10-18 17:16:11
Craig Henderson wrote:
>"Thorsten Ottosen" <nesotto_at_[hidden]> wrote in message
>news:01bc01c276bc$dbbcfc00$41c3a8c0_at_nesottolap...
>
>
>>>Many times I was missing some fundamental string manipulation routines,
>>>which are not part of STL, especially functions link trim and various
>>>conversion routines like to_upper and to_lower.
>>>
>>>
>
>Conversion of case can easily be performed with
>std::transform(str.begin(), str.end(), str.begin(), ::toupper);
>
>How do you propose a simplified version? Perhaps
>template<typename T>
>void to_upper(T &cont)
>{
> std::transform(cont.begin(), cont.end(), cont.begin(), ::toupper);
>}
>
>or something similar ?
>
>
well.. to do it right would require a bit more than that :)
(preface : i'm in a c++ channel on irc, and this is code on our bot, but
this is some of the code we have for this sorta thing, and i think it
works rather well )
//------code-----
//tolower = applies tolower on a std::string
#include <algorithm>
#include <functional>
#include <string>
#include <cctype>
std::string&
tolower (std::string &s)
{
std::transform(s.begin(), s.end(),s.begin(),
std::ptr_fun<int, int>(std::tolower));
return s;
}
//tolower = applies tolower on a char* array
#include <algorithm>
#include <functional>
#include <cctype>
#include <cstring>
char*
tolower (char buf[], size_t n)
{
std::transform(buf, buf + n,buf,
std::ptr_fun<int, int>(std::tolower));
return buf;
}
inline char*
tolower (char buf[])
{
return tolower(buf, std::strlen(buf));
}
//-----end code -----------
we also have code for trim'ing a std::string, and for trim'ing a
basic_string<>
this is that code
//---------code-------
//rtrim = trims all spaces at the end of a string
std::string&
rtrim (std::string &s)
{
s.erase(std::find_if(s.rbegin(), s.rend(),
std::not1(std::ptr_fun(std::isspace))).base(),
s.end());
return s;
}
// ltrim trims all spaces at the beginning of a string
std::string&
ltrim (std::string &s)
{
s.erase(s.begin(),
std::find_if(s.begin(), s.end(),
std::not1(std::ptr_fun(std::isspace))));
return s;
}
// an isSpace functor to make bind2nd happy
template< class charT >
struct isspaceF : public std::binary_function< charT, std::locale,
bool > {
result_type operator ()( first_argument_type c, const
second_argument_type& l ) const
{
return std::isspace( c, l );
}
};
//ltrim-generic = same as ltrim but on a basic_string<>
template< class charT, class T, class A >
std::basic_string<charT,T,A>&
ltrim( std::basic_string<charT,T,A>& s, const std::locale& l =
std::locale() )
{
s.erase( s.begin(),
std::find_if(s.begin(), s.end(),
std::not1( std::bind2nd( isspaceF<charT>(), l ) ) ) );
return s;
}
//rtrim-generic = same as rtrim on a basic_string<>
template< class charT, class T, class A >
std::basic_string<charT,T,A>&
rtrim( std::basic_string<charT,T,A>& s,
const std::locale& l = std::locale() )
{
s.erase(std::find_if(s.rbegin(), s.rend(),
std::not1(std::bind2nd(
isspaceF<charT>(),l))).base(), s.end());
return s;
}
// trim = trims all spaces on both sides of a string
std::string&
trim (std::string &s)
{
return ltrim(rtrim(s));
}
//-----end code----------
that code has been tested on vc6, vc7 , gcc2.x , and gcc 3.x , so i
can't guarantee that other compilers will compile them
properly
at any rate, that would be our contribution to this discussion :)
( i'd like to thank [eloi] and Kniht for writing the code above :)
i'd also like to thank various other members of #c++/efnet for
commenting and testing the code)
--vat
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk