Is there any easier way to trim the string? 
Author Message
 Is there any easier way to trim the string?

Is there any equalent function for MFC - CString::TrimLeft() in STL?



Fri, 07 Feb 2003 03:00:00 GMT  
 Is there any easier way to trim the string?

string s = "   untrimmed";
s.erase(0, s.find_first_not_of(" \n\r\t"));
--
With best wishes,
    Igor Tandetnik



Quote:
> Is there any equalent function for MFC - CString::TrimLeft() in STL?



Fri, 07 Feb 2003 03:00:00 GMT  
 Is there any easier way to trim the string?

Quote:
> Is there any equalent function for MFC - CString::TrimLeft() in STL?

No.  You need to program one.

Victor
--
Please remove capital A's from my address when replying by mail



Fri, 07 Feb 2003 03:00:00 GMT  
 Is there any easier way to trim the string?
If you're going for locale-safety, the code below might do.  It's a
global function ("StrTimeLeft"), not a member of basic_string, though.

Admittedly this is a bit extreme in terms of locality.  If locales are
not a factor for you, Igor's suggestion is much better.

Joe O'

template<typename CT>
 struct NotSpace : public std::unary_function<CT, bool>
 {
  const std::locale& loc;
  NotSpace(const std::locale& locArg) : loc(locArg) {}
  bool operator() (CT t) { return !std::isspace(t, loc); }
 };

 template<typename CT>
 StrTrimLeft(std::basic_string<CT>& str)
 {
  std::locale loc;
  basic_string<CT>::iterator it;
  it = std::find_if(str.begin(), str.end(), NotSpace<CT>(loc));
  if ( str.begin() != it ) // avoid  assignment when possible
  {
   basic_string<CT>::traits_type().move(
          &(*str.begin()),
                            &(*it),
          (str.end() - it+1) *sizeof(CT));
    str.resize(end() - it);
  }
 }



Quote:

> Is there any equalent function for MFC - CString::TrimLeft() in STL?



Fri, 07 Feb 2003 03:00:00 GMT  
 Is there any easier way to trim the string?

Quote:

>If you're going for locale-safety, the code below might do.  It's a
>global function ("StrTimeLeft"), not a member of basic_string, though.

>Admittedly this is a bit extreme in terms of locality.  If locales are
>not a factor for you, Igor's suggestion is much better.

A couple of comments inline.

Quote:
>Joe O'

>template<typename CT>
> struct NotSpace : public std::unary_function<CT, bool>
> {
>  const std::locale& loc;

>  NotSpace(const std::locale& locArg) : loc(locArg) {}

Having shot myself in the foot once, I like to document that the
lifetime of locArg must exceed the lifetime of instances of NotSpace.
It's very easy to pass a temporary for locArg:

// We need a NotSpace several times below, so be efficient and create
// just one, and reuse it.
NotSpace ns(locale());
// Now use NotSpace... kaboom!

Quote:
>  bool operator() (CT t) { return !std::isspace(t, loc); }

Predicates should be const functions.

Quote:
> };

> template<typename CT>
> StrTrimLeft(std::basic_string<CT>& str)
> {
>  std::locale loc;
>  basic_string<CT>::iterator it;
>  it = std::find_if(str.begin(), str.end(), NotSpace<CT>(loc));

Why not replace the following with:

 str.erase(str.begin(),it);

Quote:
>  if ( str.begin() != it ) // avoid  assignment when possible
>  {
>   basic_string<CT>::traits_type().move(

Not that it really matters, but that could be:

 traits_type::move(

Quote:
>          &(*str.begin()),
>                            &(*it),
>          (str.end() - it+1) *sizeof(CT));

You shouldn't add one here, and it's a mistake to multiply by
sizeof(CT). Length parameters in char_traits functions are defined in
terms of the specialization's char_type; they're not like memcpy and
friends, which are defined in terms of char.

Quote:
>    str.resize(end() - it);
>  }
> }

--
Doug Harrison [VC++ MVP]
Eluent Software, LLC
http://www.eluent.com
Tools for Visual C++ and Windows


Fri, 07 Feb 2003 03:00:00 GMT  
 Is there any easier way to trim the string?

Quote:

>>  traits_type::move(

>> >          &(*str.begin()),
>> >                            &(*it),
>> >          (str.end() - it+1) *sizeof(CT));

>> You shouldn't add one here, and it's a mistake to multiply by
>> sizeof(CT). Length parameters in char_traits functions are defined
>in
>> terms of the specialization's char_type; they're not like memcpy and
>> friends, which are defined in terms of char.

>I don't see how I'm assuming anything about the character type
>specifically.  CT is the template parameter for the character type.
>And a string's iterators are random access iterators.

Consider that "it" might be 5 char_type objects (or "char_types") in
front of the end. char_traits::move and other functions that have
length parameters are defined in terms of char_types. If char_type is
char, you're OK, because sizeof(char) is 1, but if it's wchar_t,
multiplying by sizeof(CT) multiplies by 2 and you try to move 10
char_types. You go way past the end of the string. You need to
multiply when using memcpy and similar functions defined in terms of
char, but not here.

Quote:
>Granted I *am* assuming that the string object's characters are
>contiguous which is not really valid.  There may not yet be any
>implementations of basic_string out there for which this hack would
>not work, but give it time and someone will write one.

I know std::vector is intended to be contiguous, and a future revision
to the standard will require it, but I don't know if basic_string will
be so constrained. It certainly should be, IMO. basic_string is so
loosely defined that to use it *portably* in any serious way would be
extremely painful.

--
Doug Harrison [VC++ MVP]
Eluent Software, LLC
http://www.eluent.com
Tools for Visual C++ and Windows



Fri, 07 Feb 2003 03:00:00 GMT  
 Is there any easier way to trim the string?
Hi Doug,

Good responses.  Yes, I should have warned about the need for the
locale object to stay around and I should have made the function
const.   And finally yes, it's a hell of a lot easier to just call
erase on  the iterator.

 One response, below:

"Doug Harrison [MVP]" wrote

Quote:

traits_type().move(

> Not that it really matters, but that could be:

>  traits_type::move(

> >          &(*str.begin()),
> >                            &(*it),
> >          (str.end() - it+1) *sizeof(CT));

> You shouldn't add one here, and it's a mistake to multiply by
> sizeof(CT). Length parameters in char_traits functions are defined
in
> terms of the specialization's char_type; they're not like memcpy and
> friends, which are defined in terms of char.

I don't see how I'm assuming anything about the character type
specifically.  CT is the template parameter for the character type.
And a string's iterators are random access iterators.

Granted I *am* assuming that the string object's characters are
contiguous which is not really valid.  There may not yet be any
implementations of basic_string out there for which this hack would
not work, but give it time and someone will write one.

But regardless it's better use erase() as you suggested.  I have no
idea what possessed me to use char_traits::move in the first place.

Joe O'



Sat, 08 Feb 2003 10:31:30 GMT  
 Is there any easier way to trim the string?

Quote:
> > Is there any equalent function for MFC - CString::TrimLeft() in STL?

MFC's TrimLeft accepts parameters and has different behavior depending if it
has parameters or not, but if all you really want is to remove leading
spaces, the following should do fine:

STD::string::size_type i = str.find_first_not_of(' ');
 if(i != STD::string::npos){
  str.erase(0, i);
 }

--
Mario Contestabile



Thu, 20 Feb 2003 12:44:22 GMT  
 
 [ 8 post ] 

 Relevant Pages 

1. Trim a comma off end of string???

2. Help to trim spaces of a string

3. trim the string

4. String.Trim() behavior

5. String.Trim is this correct functionality

6. Good ways to obfuscate/mangle strings?

7. String.Trim();

8. Need help to trim spaces off a string

9. trimming a string

10. Valid ways to pass strings

11. How to trim a string in a _variant_t

12. How to trim a String?

 

 
Powered by phpBB® Forum Software