473,507 Members | 9,962 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

The best, (right?), way to trim a char*

Hi,

I have written a function to trim char *, but I have been told that my way
could be dangerous and that I should use memmove(...) instead.
but I am not sure why my code could be 'dangerous' or even why there could
be a problem.

here is the code

////////
const char* TrimLeft( char *dest)
{
if (!dest ) return dest; //all done
size_t size = 0;
// trim left
while( size >= 0 && ( _istspace( dest[ size]) ||
dest[ size] == 10 ||
dest[ size] == 13))
{
for ( size_t loop = 0; loop < strlen( dest ) -1; loop++ )
dest[ loop] = dest[ loop +1];
dest[ strlen( dest ) -1 ] = '\0';
}
return dest;
}

const char* TrimRight( char *dest)
{
if (!dest ) return dest; //all done
int size = int(strlen( dest ));

// trim right
size--;
while( size >= 0 && ( _istspace( dest[ size]) ||
dest[ size] == 10 ||
dest[ size] == 13))
{
dest[ size] = '\0';
size--;
}
return dest;
}

const char* Trim( char *dest)
{
TrimLeft ( dest );
TrimRight ( dest );
return dest;
}

/////////////////////
// some test
/////////////////////
int main( int argc, char **argv )
{
char a[10+1];
strcpy( a, " 12345678 " );

char * b = new char[10+1];
strcpy( b, " 12345678 " );

Trim(a);
Trim(b);
// clean
delete [] b;

...
return 1;
}

/////////
Also I guess it is not really possible but I'll ask just in case, would
there be a way of trimming the memory allocated?
by that I mean if I do
char *a = new char[1024];
strcpy( a, " a " );
Trim( a);

would 'a' still have 1024 characters allocated to it or could it be
'trimmed' to 2 and free the rest of the memory?
Many thanks

Simon

Jul 22 '05 #1
22 12719
Hi,

"Simon" <sp********@schoolsofafrica.com> wrote in message
news:2q************@uni-berlin.de...
Hi,

I have written a function to trim char *, but I have been told that my way
could be dangerous and that I should use memmove(...) instead.
but I am not sure why my code could be 'dangerous' or even why there could
be a problem.

here is the code

////////
const char* TrimLeft( char *dest)
{
if (!dest ) return dest; //all done
size_t size = 0;
// trim left
while( size >= 0 && ( _istspace( dest[ size]) ||
dest[ size] == 10 ||
dest[ size] == 13))
{
for ( size_t loop = 0; loop < strlen( dest ) -1; loop++ )
dest[ loop] = dest[ loop +1];
dest[ strlen( dest ) -1 ] = '\0';
}
return dest;
} Ouch that is a lot of code even in plain C :-)

Well since this is a C++ group
#include <string>
#include <algorithm>

using namespace std;

string& TrimRight( string& String )
{
string::size_type Pos = String.find_last_not_of( ' ' ) + 1;
if( Pos < String.size() ) String.erase( Pos );
return String;
}

string& TrimLeft( string& String )
{
string::size_type Pos = String.find_first_not_of( ' ' ) ;
if( Pos < String.size() )
{
copy( String.begin() + Pos, String.end(), String.begin() );
String.erase( String.begin() + String.size() - Pos, String.end() );
}
return String;
}
Regards, Ron AF Greve.


const char* TrimRight( char *dest)
{
if (!dest ) return dest; //all done
int size = int(strlen( dest ));

// trim right
size--;
while( size >= 0 && ( _istspace( dest[ size]) ||
dest[ size] == 10 ||
dest[ size] == 13))
{
dest[ size] = '\0';
size--;
}
return dest;
}

const char* Trim( char *dest)
{
TrimLeft ( dest );
TrimRight ( dest );
return dest;
}

/////////////////////
// some test
/////////////////////
int main( int argc, char **argv )
{
char a[10+1];
strcpy( a, " 12345678 " );

char * b = new char[10+1];
strcpy( b, " 12345678 " );

Trim(a);
Trim(b);
// clean
delete [] b;

...
return 1;
}

/////////
Also I guess it is not really possible but I'll ask just in case, would
there be a way of trimming the memory allocated?
by that I mean if I do
char *a = new char[1024];
strcpy( a, " a " );
Trim( a);

would 'a' still have 1024 characters allocated to it or could it be
'trimmed' to 2 and free the rest of the memory?
No, you could try to new, copy and delete the original but usual the
performance penalty doesn't outweigh a possible but not guarenteed memory
gain.

Regards, Ron AF Greve
Many thanks

Simon

Jul 22 '05 #2

"Simon" <sp********@schoolsofafrica.com> wrote in message
news:2q************@uni-berlin.de...
Hi,

I have written a function to trim char *, but I have been told that my way
could be dangerous and that I should use memmove(...) instead.
but I am not sure why my code could be 'dangerous' or even why there could
be a problem.

There is no problem I can see, except that your TrimLeft function is
inefficient. You should count the number of whitespace chars at the
beginning of the string and copy backward once only. The way you are doing
it if there are multiple whitespace chars at the beginning of your string
then you copy backward repeatedly.

The person you are talking is probably garbling advice about when to use
memcpy and when to use memmove, but thats not relevant to your case since
you aren't using memcpy.
here is the code

////////
const char* TrimLeft( char *dest)
{
if (!dest ) return dest; //all done
size_t size = 0;
// trim left
while( size >= 0 && ( _istspace( dest[ size]) ||
dest[ size] == 10 ||
dest[ size] == 13))
{
for ( size_t loop = 0; loop < strlen( dest ) -1; loop++ )
dest[ loop] = dest[ loop +1];
dest[ strlen( dest ) -1 ] = '\0';
}
return dest;
}

const char* TrimRight( char *dest)
{
if (!dest ) return dest; //all done
int size = int(strlen( dest ));

// trim right
size--;
while( size >= 0 && ( _istspace( dest[ size]) ||
dest[ size] == 10 ||
dest[ size] == 13))
{
dest[ size] = '\0';
size--;
}
return dest;
}

const char* Trim( char *dest)
{
TrimLeft ( dest );
TrimRight ( dest );
return dest;
}

/////////////////////
// some test
/////////////////////
int main( int argc, char **argv )
{
char a[10+1];
strcpy( a, " 12345678 " );

char * b = new char[10+1];
strcpy( b, " 12345678 " );

Trim(a);
Trim(b);
// clean
delete [] b;

...
return 1;
}

/////////
Also I guess it is not really possible but I'll ask just in case, would
there be a way of trimming the memory allocated?
by that I mean if I do
char *a = new char[1024];
strcpy( a, " a " );
Trim( a);

would 'a' still have 1024 characters allocated to it or could it be
'trimmed' to 2 and free the rest of the memory?


Use the std::string class instead, easier, safer, more efficient and real
C++. At the moment you are coding C not C++.Get a book on C++ that explains
about the standard C++ library, e.g. 'The C++ Standard Library' by Josuttis.

john
Jul 22 '05 #3

"Simon" <sp********@schoolsofafrica.com> wrote in message
news:2q************@uni-berlin.de...
Hi,

I have written a function to trim char *, but I have been told that my way
could be dangerous and that I should use memmove(...) instead.
but I am not sure why my code could be 'dangerous' or even why there could
be a problem.

here is the code

////////
const char* TrimLeft( char *dest)
you take in a char*, but return the same as a const char*. Did you really
mean to do that?

{
if (!dest ) return dest; //all done
size_t size = 0;
// trim left
while( size >= 0 && ( _istspace( dest[ size]) ||
dest[ size] == 10 ||
dest[ size] == 13))
{
for ( size_t loop = 0; loop < strlen( dest ) -1; loop++ )
dest[ loop] = dest[ loop +1];
dest[ strlen( dest ) -1 ] = '\0';
}
return dest;
}


Very inefficient. You have an O(n^3) algorithm (while * for * strlen) for
what should only be a linear one.
how about:

void trim_left(char* s)
{
size_t sz = strlen(s);
char* p = find(s, s + sz, not1(isspace)));
if (p != s && p != s + sz)
memmove(s, p, sz - (p - s) + 1);
}

or if you are just going to return the pointer, just return p instead of
moving the chars.

Jul 22 '05 #4
If you take in a char*, the simply set the appropriate char
to '\0', ending the string.

If you take in const char*, allocate an appropriate block
of memory, then copy.
-JKop
Jul 22 '05 #5
"Xenos" <do**********@spamhate.com> wrote in message
news:ch*********@cui1.lmms.lmco.com...

void trim_left(char* s)
{
size_t sz = strlen(s);
char* p = find(s, s + sz, not1(isspace)));
if (p != s && p != s + sz)
memmove(s, p, sz - (p - s) + 1);
}

or if you are just going to return the pointer, just return p instead of moving the chars.


Cute idea, but that would make the buffer "smaller". If the calling
function expects to have 1024 chars to work with and thinks trim_left("
3 spaces"); has moved everything as far left as possible, then it thinks
it has 1016 chars left in the buffer, but it would really only have
1013.

--
Mabden
Jul 22 '05 #6

"JKop" <NU**@NULL.NULL> wrote in message
news:9c******************@news.indigo.ie...
If you take in a char*, the simply set the appropriate char
to '\0', ending the string.

Note: that only works for TrimRight, not for TrimLeft.
If you take in const char*, allocate an appropriate block
of memory, then copy.


The original functions given by the OP had non-const parameters, and
modified the strings in-place, so that's not what was wanted. To trim left
in-place, a memmove should be used (but preferably only once!).

(I wonder why those functions return a value, though, considering the return
value is ignored and the operations are done in-place...?)

-Howard


Jul 22 '05 #7
>
The original functions given by the OP had non-const parameters, and
modified the strings in-place, so that's not what was wanted. To trim left in-place, a memmove should be used (but preferably only once!).

(I wonder why those functions return a value, though, considering the return value is ignored and the operations are done in-place...?)
No reason really, I have removed the return values that were not really
needed in the first place.
-Howard


Simon
Jul 22 '05 #8
> > Hi,

I have written a function to trim char *, but I have been told that my way could be dangerous and that I should use memmove(...) instead.
but I am not sure why my code could be 'dangerous' or even why there could be a problem.

here is the code

////////
const char* TrimLeft( char *dest)
you take in a char*, but return the same as a const char*. Did you really
mean to do that?


Not really, I removed it as I have no use for it.
Could it have caused problems?

Very inefficient. You have an O(n^3) algorithm (while * for * strlen) for
what should only be a linear one.
how about:

void trim_left(char* s)
{
size_t sz = strlen(s);
char* p = find(s, s + sz, not1(isspace)));
if (p != s && p != s + sz)
memmove(s, p, sz - (p - s) + 1);
}

or if you are just going to return the pointer, just return p instead of
moving the chars.


Indeed.

Thanks

Simon
Jul 22 '05 #9
> > Hi,

Ouch that is a lot of code even in plain C :-)

Well since this is a C++ group
#include <string>
#include <algorithm>

using namespace std;

string& TrimRight( string& String )
{
string::size_type Pos = String.find_last_not_of( ' ' ) + 1;
if( Pos < String.size() ) String.erase( Pos );
return String;
}

string& TrimLeft( string& String )
{
string::size_type Pos = String.find_first_not_of( ' ' ) ;
if( Pos < String.size() )
{
copy( String.begin() + Pos, String.end(), String.begin() );
String.erase( String.begin() + String.size() - Pos, String.end() );
}
return String;
}
Regards, Ron AF Greve.


I see your point but the function is used all over the place and changing it
to std::string(...) would be quite a challenge.

Simon
Jul 22 '05 #10
Simon wrote:

You need to handle the return value of string::npos in your code.
Jul 22 '05 #11
Okay here we go:

A) Trim off left

B) Trim off right

1) Takes in char*

2) Takes in const char*
[A1] Just return a char* that points to the starting
character

[A2] Just return a const char* that points to the starting
character

[B1] Set the char after the last character in the string to
'\0', returning a char*

[B2] Allocate new memory, copy it over, returning a char*
OR a const char*, whatever tickles your fancy.
-JKop
Jul 22 '05 #12
Hi,

"red floyd" <no*****@here.dude> wrote in message
news:qo*******************@newssvr27.news.prodigy. com...
Simon wrote:

You need to handle the return value of string::npos in your code.


I just grabbed some old code and probably would have done it different now.

I agree with you that the code is theoratically not 100% correct, I should
have checked for string::npos (I check for a valid Pos instead). However it
is reasonable to assume that size_type is an unsigned type and npos is
static_cast<unsigned type>( -1 ). In theory its wrong in practice it works
and is efficient.

Regards, Ron AF Greve
Jul 22 '05 #13
> > Simon wrote:

You need to handle the return value of string::npos in your code.
I just grabbed some old code and probably would have done it different

now.
I agree with you that the code is theoratically not 100% correct, I should
have checked for string::npos (I check for a valid Pos instead). However it is reasonable to assume that size_type is an unsigned type and npos is
static_cast<unsigned type>( -1 ). In theory its wrong in practice it works
and is efficient.

Regards, Ron AF Greve


Sorry guys I really do not mean to be rude, but I am lost in my C world
here, what is the "npos" for and what are you guys talking about?
I know i am in a C++ group but i think i missed a message somewhere.

Simon
Jul 22 '05 #14
Hi,

"Simon" <sp********@schoolsofafrica.com> wrote in message
news:2q************@uni-berlin.de...
> Simon wrote:
>
> You need to handle the return value of string::npos in your code.
I just grabbed some old code and probably would have done it different

now.

I agree with you that the code is theoratically not 100% correct, I
should
have checked for string::npos (I check for a valid Pos instead). However

it
is reasonable to assume that size_type is an unsigned type and npos is
static_cast<unsigned type>( -1 ). In theory its wrong in practice it
works
and is efficient.

Regards, Ron AF Greve


Sorry guys I really do not mean to be rude, but I am lost in my C world
here, what is the "npos" for and what are you guys talking about?
I know i am in a C++ group but i think i missed a message somewhere.


string::npos

is returned when something can't be found. Sort of "Invalid position" could
be theoratically anything as long as it is not a valid position of course.
In practice it usually is the unsigned equivalent of -1.

So I should have written "Pos != string::npos" and change the function a
bit.
Regards, Ron AF Greve.

Simon

Jul 22 '05 #15
"Moonlit" <news moonlit xs4all nl> wrote in message
news:41***********************@news.xs4all.nl...
Hi,

"Simon" <sp********@schoolsofafrica.com> wrote in message
news:2q************@uni-berlin.de...
> Simon wrote:
>
> You need to handle the return value of string::npos in your code.

I just grabbed some old code and probably would have done it different now.

I agree with you that the code is theoratically not 100% correct, I
should
have checked for string::npos (I check for a valid Pos instead).
However it
is reasonable to assume that size_type is an unsigned type and npos is
static_cast<unsigned type>( -1 ). In theory its wrong in practice it
works
and is efficient.

Regards, Ron AF Greve


Sorry guys I really do not mean to be rude, but I am lost in my C world
here, what is the "npos" for and what are you guys talking about?
I know i am in a C++ group but i think i missed a message somewhere.


string::npos

is returned when something can't be found. Sort of "Invalid position"

could be theoratically anything as long as it is not a valid position of course.
In practice it usually is the unsigned equivalent of -1.

So I should have written "Pos != string::npos" and change the function a
bit.
Regards, Ron AF Greve.


std::basic_string<T>::npos is -1 (see 21.3), and, AFAIK, size_type is
required to be an unsigned integral type (see 20.1.5). This renders many
checks against std::string::npos unnecessary. Moonlit's code seems to be
doing more work than is necessary.

--
David Hilsee
Jul 22 '05 #16
Hi,

"David Hilsee" <da*************@yahoo.com> wrote in message
news:oZ********************@comcast.com...
"Moonlit" <news moonlit xs4all nl> wrote in message
news:41***********************@news.xs4all.nl...
Hi,

"Simon" <sp********@schoolsofafrica.com> wrote in message
news:2q************@uni-berlin.de...
>> > Simon wrote:
>> >
>> > You need to handle the return value of string::npos in your code.
>>
>> I just grabbed some old code and probably would have done it different
> now.
>>
>> I agree with you that the code is theoratically not 100% correct, I
>> should
>> have checked for string::npos (I check for a valid Pos instead). However > it
>> is reasonable to assume that size_type is an unsigned type and npos is
>> static_cast<unsigned type>( -1 ). In theory its wrong in practice it
>> works
>> and is efficient.
>>
>> Regards, Ron AF Greve
>>
>
> Sorry guys I really do not mean to be rude, but I am lost in my C world
> here, what is the "npos" for and what are you guys talking about?
> I know i am in a C++ group but i think i missed a message somewhere.
string::npos

is returned when something can't be found. Sort of "Invalid position"

could
be theoratically anything as long as it is not a valid position of
course.
In practice it usually is the unsigned equivalent of -1.

So I should have written "Pos != string::npos" and change the function a
bit.
Regards, Ron AF Greve.


std::basic_string<T>::npos is -1 (see 21.3), and, AFAIK, size_type is
required to be an unsigned integral type (see 20.1.5). This renders many
checks against std::string::npos unnecessary. Moonlit's code seems to be


The complaint was, I didn't check against string::npos :-)
You do have to check if something is found like I did. Could you write those
few lines even shorter?

Regards, Ron AF Greve
doing more work than is necessary.

Good you give us an example of shorter code.

(always trying to improve)
--
David Hilsee


Regards, Ron AF Greve
Jul 22 '05 #17
"Moonlit" <news moonlit xs4all nl> wrote in message
news:41*********************@news.xs4all.nl...
<snip>
std::basic_string<T>::npos is -1 (see 21.3), and, AFAIK, size_type is
required to be an unsigned integral type (see 20.1.5). This renders many checks against std::string::npos unnecessary. Moonlit's code seems to
be
The complaint was, I didn't check against string::npos :-)
You do have to check if something is found like I did. Could you write those few lines even shorter?

Regards, Ron AF Greve
doing more work than is necessary.


Good you give us an example of shorter code.

(always trying to improve)


Sure. Often times, there is no need to check against npos because the type
is unsigned and the value is -1 (well, which is translated to the largest
value that type can hold). Unsigned types have useful "wrap around"
properties when you perform computations on them. Also, some of
std::string's member functions have nice, expected, and well-defined
behavior when passed npos.

// #include <iostream>, <string>, etc
string& TrimRight( string& String ) {
// When find_last_not_of returns npos, Pos becomes 0
string::size_type Pos = String.find_last_not_of( ' ' ) + 1;
String.erase( Pos );
return String;
}

string& TrimLeft( string& String ) {
string::size_type Pos = String.find_first_not_of( ' ' ) ;
String.erase( 0, Pos );
return String;
}
int main() {
std::string testStrings[] = {
"test", " test2 ", "", " ", " a", " ", " a",
" a", "a", "a ", "a "
};
int numTests = sizeof(testStrings)/sizeof(testStrings[0]);
for ( int i = 0; i < numTests; ++i ) {
std::string orig = testStrings[i];
std::cout << "'" << orig << "':";
std::cout << " Left trim: '" << TrimLeft(orig) << "'";
orig = testStrings[i];
std::cout << " Right trim: '" << TrimRight(orig) << "'";
std::cout << std::endl;
}
return 0;
}

Output:
'test': Left trim: 'test' Right trim: 'test'
' test2 ': Left trim: 'test2 ' Right trim: ' test2'
'': Left trim: '' Right trim: ''
' ': Left trim: '' Right trim: ''
' a': Left trim: 'a' Right trim: ' a'
' ': Left trim: '' Right trim: ''
' a': Left trim: 'a' Right trim: ' a'
' a': Left trim: 'a' Right trim: ' a'
'a': Left trim: 'a' Right trim: 'a'
'a ': Left trim: 'a ' Right trim: 'a'
'a ': Left trim: 'a ' Right trim: 'a'

BTW, the TrimLeft function you originally provided didn't handle the empty
strings the way I expected it should. You could have added an additional
check for npos to fix it, but it was best to remove the check against the
size of the string.

Original code's output (with main above):
'test': Left trim: 'test' Right trim: 'test'
' test2 ': Left trim: 'test2 ' Right trim: ' test2'
'': Left trim: '' Right trim: ''
' ': Left trim: ' ' Right trim: ''
' a': Left trim: 'a' Right trim: ' a'
' ': Left trim: ' ' Right trim: ''
' a': Left trim: 'a' Right trim: ' a'
' a': Left trim: 'a' Right trim: ' a'
'a': Left trim: 'a' Right trim: 'a'
'a ': Left trim: 'a ' Right trim: 'a'
'a ': Left trim: 'a ' Right trim: 'a'

--
David Hilsee
Jul 22 '05 #18
Hi,

"David Hilsee" <da*************@yahoo.com> wrote in message
news:BZ********************@comcast.com...
"Moonlit" <news moonlit xs4all nl> wrote in message
news:41*********************@news.xs4all.nl...
<snip>
> std::basic_string<T>::npos is -1 (see 21.3), and, AFAIK, size_type is
> required to be an unsigned integral type (see 20.1.5). This renders many > checks against std::string::npos unnecessary. Moonlit's code seems to

be

The complaint was, I didn't check against string::npos :-)
You do have to check if something is found like I did. Could you write

those
few lines even shorter?

Regards, Ron AF Greve
> doing more work than is necessary.
>


Good you give us an example of shorter code.

(always trying to improve)


Sure. Often times, there is no need to check against npos because the
type
is unsigned and the value is -1 (well, which is translated to the largest
value that type can hold). Unsigned types have useful "wrap around"
properties when you perform computations on them. Also, some of
std::string's member functions have nice, expected, and well-defined
behavior when passed npos.

// #include <iostream>, <string>, etc
string& TrimRight( string& String ) {
// When find_last_not_of returns npos, Pos becomes 0
string::size_type Pos = String.find_last_not_of( ' ' ) + 1;
String.erase( Pos );
return String;
}

string& TrimLeft( string& String ) {
string::size_type Pos = String.find_first_not_of( ' ' ) ;
String.erase( 0, Pos );
return String;
}
int main() {
std::string testStrings[] = {
"test", " test2 ", "", " ", " a", " ", " a",
" a", "a", "a ", "a "
};
int numTests = sizeof(testStrings)/sizeof(testStrings[0]);
for ( int i = 0; i < numTests; ++i ) {
std::string orig = testStrings[i];
std::cout << "'" << orig << "':";
std::cout << " Left trim: '" << TrimLeft(orig) << "'";
orig = testStrings[i];
std::cout << " Right trim: '" << TrimRight(orig) << "'";
std::cout << std::endl;
}
return 0;
}

Output:
'test': Left trim: 'test' Right trim: 'test'
' test2 ': Left trim: 'test2 ' Right trim: ' test2'
'': Left trim: '' Right trim: ''
' ': Left trim: '' Right trim: ''
' a': Left trim: 'a' Right trim: ' a'
' ': Left trim: '' Right trim: ''
' a': Left trim: 'a' Right trim: ' a'
' a': Left trim: 'a' Right trim: ' a'
'a': Left trim: 'a' Right trim: 'a'
'a ': Left trim: 'a ' Right trim: 'a'
'a ': Left trim: 'a ' Right trim: 'a'

BTW, the TrimLeft function you originally provided didn't handle the empty
strings the way I expected it should. You could have added an additional
check for npos to fix it, but it was best to remove the check against the
size of the string.

Original code's output (with main above):
'test': Left trim: 'test' Right trim: 'test'
' test2 ': Left trim: 'test2 ' Right trim: ' test2'
'': Left trim: '' Right trim: ''
' ': Left trim: ' ' Right trim: ''
' a': Left trim: 'a' Right trim: ' a'
' ': Left trim: ' ' Right trim: ''
' a': Left trim: 'a' Right trim: ' a'
' a': Left trim: 'a' Right trim: ' a'
'a': Left trim: 'a' Right trim: 'a'
'a ': Left trim: 'a ' Right trim: 'a'
'a ': Left trim: 'a ' Right trim: 'a'

--
David Hilsee

You code is indeed a lot shorter. I didn't know I could just pass npos to
those functions.

Well as they say a day without learning anything, is a day lost :-)

Thanks, Ron AF Greve
Jul 22 '05 #19
Simon wrote:

Hi,

I have written a function to trim char *, but I have been told that my way
could be dangerous and that I should use memmove(...) instead.
but I am not sure why my code could be 'dangerous' or even why there could
be a problem.


This doesn't allocate or move memory, but operates on the source string:
char * TrimLeft(char * string)
{
while (string && *string && isspace(*string))
{
++string;
}
return string;
}

char * TrimRight(char * string)
{
char * end = (string && *string) ? &string[strlen(string)-1] : 0;
while (end && end>=string && isspace(*end))
{
*end = '\0';
}
return string;
}

char * Trim(char * string)
{
return TrimLeft(TrimRight(string));
}
Jul 22 '05 #20
Julie <ju***@nospam.com> writes:
Simon wrote:

Hi,

I have written a function to trim char *, but I have been told that my way
could be dangerous and that I should use memmove(...) instead.
but I am not sure why my code could be 'dangerous' or even why there could
be a problem.


I don't know the problem but why not use std::string instad of raw char*?
std::string also supports trimming of strings, and there is no overhead of
memory.

Kind regards,
Nicolas

--
| Nicolas Pavlidis | Elvis Presly: |\ |__ |
| Student of SE & KM | "Into the goto" | \|__| |
| pa****@sbox.tugraz.at | ICQ #320057056 | |
|-------------------University of Technology, Graz----------------|
Jul 22 '05 #21
Julie wrote:

Simon wrote:

Hi,

I have written a function to trim char *, but I have been told that my way
could be dangerous and that I should use memmove(...) instead.
but I am not sure why my code could be 'dangerous' or even why there could
be a problem.


This doesn't allocate or move memory, but operates on the source string:


<see previous post>

Bug in TrimRight, should be:

char * TrimRight(char * string)
{
char * end = (string && *string) ? &string[strlen(string)-1] : 0;
while (end && end>=string && isspace(*end))
{
*end = '\0';
--end;
}
return string;
}
Jul 22 '05 #22
"Julie" <ju***@nospam.com> wrote in message
news:41***************@nospam.com...
Julie wrote:

Simon wrote:

Hi,

I have written a function to trim char *, but I have been told that my way could be dangerous and that I should use memmove(...) instead.
but I am not sure why my code could be 'dangerous' or even why there could be a problem.


This doesn't allocate or move memory, but operates on the source string:


<see previous post>

Bug in TrimRight, should be:

char * TrimRight(char * string)
{
char * end = (string && *string) ? &string[strlen(string)-1] : 0;
while (end && end>=string && isspace(*end))
{
*end = '\0';
--end;
}
return string;
}


I don't think your "end >= string" check is portable. IIRC,
less-than/greater-than/etc pointer comparisons are only valid if the pointer
points to something inside the block of memory or one beyond the last
element. If you move the pointer to just before the first element, you
can't expect the comparison to work on all platforms. In practice, it
generally works, though.

For a quick fix, you could remove the >= test and instead insert a break
when end == string, or count the characters overwritten, comparing it
against what strlen() returned so you know when to stop.

--
David Hilsee
Jul 22 '05 #23

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
2176
by: MLH | last post by:
I want to change my system time date each time an A97 app is started. Here's how I've been doing it. Am looking for a better way. Sure some of you have researched this. Function...
9
6264
by: Durgesh Sharma | last post by:
Hi All, Pleas help me .I am a starter as far as C Language is concerned . How can i Right Trim all the white spaces of a very long (2000 chars) Charecter string ( from the Right Side ) ? or how...
8
2126
by: sengkok | last post by:
I have develop a smart card device reading and writing program, but I am facing a problem that when I read the value from the smart card, I get "A19\0 \0\0\0", (actually I have store the value A19...
3
2677
by: Raed Sawalha | last post by:
I have the following letters; string letters = "a;b;c....to z"; the I need to replace the incoming string which containing letters above with integer 1 i did following for(int...
11
5325
by: Darren Anderson | last post by:
I have a function that I've tried using in an if then statement and I've found that no matter how much reworking I do with the code, the expected result is incorrect. the code: If Not...
2
1922
by: Anthony Biondo Jr | last post by:
I am trying to figure out the best way to return data through a web service. If the value is a single value I can just set it equal to the web service name. If I am returning a set of data I have...
31
2865
by: rkk | last post by:
Hi, I've written a small trim function to trim away the whitespaces in a given string. It works well with solaris forte cc compiler, but on mingw/cygwin gcc it isn't. Here is the code: char...
121
4990
by: swengineer001 | last post by:
Just looking for a few eyes on this code other than my own. void TrimCString(char *str) { // Trim whitespace from beginning: size_t i = 0; size_t j; while(isspace(str)) {
0
7109
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7313
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7372
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
7481
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
5619
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
1
5039
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3179
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
758
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
411
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.