CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 14 of 14
  1. #1
    Join Date
    Jul 2010
    Posts
    75

    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.

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    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.

  3. #3
    Join Date
    Jul 2010
    Posts
    75

    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;
    }

  4. #4
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: Left trim a char*

    That doesn't address any of the points Lindley made.

  5. #5
    Join Date
    Jul 2010
    Posts
    75

    Re: Left trim a char*

    Quote Originally Posted by Lindley View Post
    the a in main should be a const char*
    Code:
    const char *a = trim("   asd");
    That's one point.

  6. #6
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: Left trim a char*

    Quote Originally Posted by paprica View Post
    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.

  7. #7
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Left trim a char*

    Quote Originally Posted by paprica View Post
    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

  8. #8
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Left trim a char*

    Quote Originally Posted by paprica View Post
    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.

  9. #9
    GCDEF is offline Elite Member Power Poster
    Join Date
    Nov 2003
    Location
    Florida
    Posts
    12,635

    Re: Left trim a char*

    Quote Originally Posted by Lindley View Post
    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?

  10. #10
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Left trim a char*

    I usually assume string literals have static scope.

  11. #11
    Join Date
    Apr 2010
    Posts
    20

    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.

  12. #12
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Left trim a char*

    Quote Originally Posted by CppCoder2010 View Post
    [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

  13. #13
    Join Date
    Jul 2010
    Posts
    75

    Re: Left trim a char*

    I see.
    What's the difference between these two?
    Code:
    const char *a = "asdasd";
    const char a[] = "asdasd";

  14. #14
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Left trim a char*

    Quote Originally Posted by paprica View Post
    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
  •  





Click Here to Expand Forum to Full Width

Featured