-
August 24th, 2011, 07:42 AM
#1
Left trim a char*
Hello.
What is wrong with my code?
Code:
#include <iostream>
using namespace std;
void trim(char *a)
{
while(isspace(*a))
a++;
}
int main()
{
char *a = " asdasd";
trim(a);
cout << a << endl;
return 0;
}
" asdasd" is still displayed.
-
August 24th, 2011, 07:47 AM
#2
Re: Left trim a char*
The "a" pointer that you're modifying is local to the function, so when it returns you do not retain the new value.
A second problem is that the a in main should be a const char* if it is defined to point at a string literal, since it is illegal to modify a string literal. Some compilers will warn you about this, others won't.
A third potential problem is that your method of trimming----simply adjusting the pointer----will only work for string literals. It won't work for arrays on the stack (you can't modify where they begin), and it won't work for char arrays on the heap because you'd lose the ability to release that memory if you modify the starting pointer.
-
August 24th, 2011, 08:04 AM
#3
Re: Left trim a char*
I see.
How's this?
Code:
char* trim(char *a)
{
while(isspace(*a))
a++;
return a;
}
int main()
{
const char *a = trim(" asd");
cout << a << endl;
system("pause");
return 0;
}
-
August 24th, 2011, 08:06 AM
#4
Re: Left trim a char*
That doesn't address any of the points Lindley made.
-
August 24th, 2011, 08:14 AM
#5
Re: Left trim a char*
Originally Posted by Lindley
the a in main should be a const char*
Code:
const char *a = trim(" asd");
That's one point.
-
August 24th, 2011, 08:23 AM
#6
Re: Left trim a char*
Originally Posted by paprica
Code:
const char *a = trim(" asd");
That's one point.
But the point was that you can't modify a string literal. Your whole approach needs to be changed. You're not actually trimming anything.
-
August 24th, 2011, 08:47 AM
#7
Re: Left trim a char*
Originally Posted by paprica
Code:
const char *a = trim(" asd");
That's one point.
First, the title of your post indicates the trouble that you're getting yourself into.
You cannot trim a "char*". The reason is that a char* is a pointer. It is not a string. You cannot "trim" a pointer, and your efforts shows the effect of trying to do something that can't be done.
What you're trying to do is remove spaces from an array of char. The problem with that is that you can't remove spaces from an array -- you can't remove anything from an array since an array is fixed in size. You can change items in an array, but not remove (or add) items to an array. So how are you going to trim or remove items from an array when arrays can't be shrunk (or grown)?
Third, you are attempting to change a string-literal, and as the others have pointed out, you cannot change a string-literal. Example:
Code:
int main()
{
char *a = "abc123";
a[0] = 'x';
}
If you compiled and run this code, the program may possibly crash where you are changing the first character to 'x'. The reason is that "a" is really a string-literal (const char*), and you cannot modify literals.
Last, let's say you did move the pointer to where the non-space character starts. What if the original pointer points to a block allocated with "new"? You've just messed up the pointer so that deleting the pointer will fail, since it no longer points to the original location. You have now created a maintenance nightmare.
This and other problems is what a 'C' programmer encounters, since "strings" exist in 'C' as a null-terminated array of char. The 'C' programmer has to think very carefully about different strategies on how to accomplish this seemingly simple task of removing spaces from a beginning of an array. Usually they wind up malloc()-ing a new array of char and copying the trimmed version of the string to this array (and then return the pointer). Of course, this also has problems in that the user of the function must remember to "free()" the pointer.
But you're not using 'C -- you're using C++. So why get yourself into this mess to begin with? Quit using char pointers as strings, and instead use proper classes that represent strings, such as std::string. Then you can trim std::string's, since they are dynamic and are built to be changed and modified.
Regards,
Paul McKenzie
-
August 24th, 2011, 09:59 AM
#8
Re: Left trim a char*
Originally Posted by paprica
Code:
const char *a = trim(" asd");
That's one point.
Make the trim function take and return const char*s as well, and you're good enough for the moment. The caveat, as has been mentioned, is that this isn't really trimming----it's just advancing a pointer to ignore part of the underlying char array.
This is fine in certain situations, but not in every situation. Therefore, you'll need to make sure that your function is well-documented so there's no question as to what it actually does.
-
August 24th, 2011, 10:03 AM
#9
Re: Left trim a char*
Originally Posted by Lindley
Make the trim function take and return const char*s as well, and you're good enough for the moment. The caveat, as has been mentioned, is that this isn't really trimming----it's just advancing a pointer to ignore part of the underlying char array.
This is fine in certain situations, but not in every situation. Therefore, you'll need to make sure that your function is well-documented so there's no question as to what it actually does.
I should know but I'm not sure at this point, what is the scope of that string literal in his last attempt?
-
August 24th, 2011, 10:27 AM
#10
Re: Left trim a char*
I usually assume string literals have static scope.
-
August 24th, 2011, 10:59 AM
#11
Re: Left trim a char*
Code:
std::string LeftTrim(const char * pString)
{
while (*pString == ' ')
{
++pString;
}
std::string retValue(pString);
return retValue;
}
std::string LeftTrim(const char * pString,const char * pCharSet)
{
bool bFound;
while (true)
{
bFound = false;
const char * pSet = pCharSet;
while (bFound == false && *pSet != 0)
{
if (*pString == *pSet)
{
++pString;
bFound = true;
}
else
{
++pSet;
}
}
if (bFound == false)
{
break;
}
}
std::string strRetValue(pString);
return strRetValue;
}
Last edited by CppCoder2010; August 24th, 2011 at 11:07 AM.
-
August 24th, 2011, 11:23 AM
#12
Re: Left trim a char*
Originally Posted by CppCoder2010
[code]
std::string LeftTrim(const char * pString)
What would happen if I called your function like this:
Code:
char *p = 0;
LeftTrim( p );
Secondly, trimming a string has been discussed here, using algorithms instead of hand-written loops.
http://www.codeguru.com/forum/showthread.php?t=513826
Regards,
Paul McKenzie
-
August 24th, 2011, 11:58 AM
#13
Re: Left trim a char*
I see.
What's the difference between these two?
Code:
const char *a = "asdasd";
const char a[] = "asdasd";
-
August 24th, 2011, 12:06 PM
#14
Re: Left trim a char*
Originally Posted by paprica
I see.
What's the difference between these two?
Code:
const char *a = "asdasd";
const char a[] = "asdasd";
The first defines a pointer. The pointer can be modified, but what it points to cannot. The pointer is initialized to point at a block of global read-only memory containing the string "asdasd".
The second defines an array on the stack. Neither the array's address nor its contents will be modifiable in the future (if you drop the const its contents will be, but array addresses can never be changed). Since no size is explicitly specified, the size is deduced from the initializer to be 7, and the contents are initialized to {a,s,d,a,s,d,0}.
The second is a better choice if you wish to modify the C-style string at some point in the future (dropping the const of course). The first is a better choice for "reference strings" that will never need to be changed, just used.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|