473,714 Members | 2,513 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 12752
Hi,

"Simon" <sp********@sch oolsofafrica.co m> 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_ty pe Pos = String.find_las t_not_of( ' ' ) + 1;
if( Pos < String.size() ) String.erase( Pos );
return String;
}

string& TrimLeft( string& String )
{
string::size_ty pe Pos = String.find_fir st_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********@sch oolsofafrica.co m> 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********@sch oolsofafrica.co m> 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**********@s pamhate.com> wrote in message
news:ch******** *@cui1.lmms.lmc o.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_ty pe Pos = String.find_las t_not_of( ' ' ) + 1;
if( Pos < String.size() ) String.erase( Pos );
return String;
}

string& TrimLeft( string& String )
{
string::size_ty pe Pos = String.find_fir st_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

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

Similar topics

1
2191
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 SnatchInterNETTD(): '*********************************************************************** ' Internet lookup used to retrieve correct time and date. ' Remove instances of "FUCKING". I could not make this ' post stick unless I changed eBay to eFUCKINGBay. Sorry...
9
6276
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 can i make a fast Right Trim Function in c,using Binary search kind of fast algorithm ? Offcourse...I can use the classical approach too. like : Start from the right most charecter of the string to the left of the
8
2137
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 into the card from sector 17 to sector 24, 8 bytes long), I try to use Trim () function to cut the unnecessary variable to get back the value A19, but it seen that the \0 is not an null character. I have tried to trim “\0”, but it is not...
3
2695
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 u=0;u<letters.Split(';').Length;u++) { FilesName = FilesName.Trim().Replace(letters.Split(';'), "1"); }
11
5351
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 (strIn.Substring(410, 10).Trim = "") Then 'Something processed Else 'Something processed
2
1931
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 seen a couple ways to do this. The dataset coming back to me is a SybaseASE Data Reader. Any help you can provide would be much appreciated. thanks, Anthony Right now I have done the following:
31
2905
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 *trim(char *s) { char *begin,*end; begin = s;
121
5110
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
8797
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, well explore What is ONU, What Is Router, ONU & Routers main usage, and What is the difference between ONU and Router. Lets take a closer look ! Part I. Meaning of...
0
8704
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9309
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9171
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9071
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9010
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 protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
5945
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4717
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3156
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.