Thread: Trim leading spaces on a string (without returning a new string)

  1. #1
    Registered User
    Join Date
    Apr 2010
    Posts
    12

    Question Trim leading spaces on a string (without returning a new string)

    I wrote a quick function to trim trailing spaces on a string without generating a new string...
    Code:
    void rtrim (char * s ) {
      int end;
      end = strlen(s) - 1;
      if (end >= 0 && s[end] == '\n')
        s[end] = '\0';
    }
    Doing it on leading spaces is more complicated. I particularly don't want something that generates a new string. Something I can call like this:

    Code:
    ltrim(somestring);
    I can't be the first person to do this - rather than invent the wheel, does someone have code or a pointer to some code?

    I'm thinking something that uses memmove() would be the solution...? Or perhaps there's a different technique...?

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,656
    Using memmove is one way.

    Or your own copy, starting from the first non-space char, to the beginning of the string.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Apr 2010
    Posts
    4

    Red face

    Code:
    strcpy(testString,"              now I am learning programming");
    
    char * tmp = testString;
    int i;
    
    while (*tmp == ' ') {
    	*tmp++;
    }
    i = 0;
    while (*tmp != NULL) {
    	testString[i++] = *tmp++;
    }
    testString[i] = '\0';
    
    printf("Adjusted: %s\n",testString);
    -----------
    Beginner Computer Programming
    teaching programming to beginners using C

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    john runchey, you might want to remove that dereference of tmp in the first loop, and then you should be comparing *tmp with '\0', not NULL, even though they evaluate to the same integer value.

    EDIT:
    monk64, there is a slight problem with your rtrim function though. strlen() returns a size_t, which is an unsigned integer type. This means that strlen(s) - 1 on an empty string would not produce a negative value. In fact, it would result in a value that probably is not in the range of an int. Furthermore, it seems that all you are doing is removing a trailing newline character, if it exists, rather than removing trailing spaces.
    Last edited by laserlight; 04-13-2010 at 06:12 AM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Apr 2010
    Posts
    4
    Good point - too early in the morning for coding

    Quote Originally Posted by john runchey View Post
    Code:
    while (*tmp == ' ') {
    	tmp++;
    }
    -----------
    Beginner Computer Programming
    teaching programming to beginners using C

  6. #6
    Registered User
    Join Date
    Dec 2010
    Posts
    1

    try sscanf

    Someone mentioned something about not reinventing the wheel...

    sscanf with %s will read a string within a string containing leading/trailing whitespace

    Using scansets you can trim other leading/trailing chars like delimeters

  7. #7
    Registered User
    Join Date
    Aug 2010
    Posts
    231
    Code:
    char *rtrim(char *s)
    {
      while( *s && s[strlen(s)-1]==' ' )
        s[strlen(s)-1]=0;
      return s;
    }
    
    char *ltrim(char *s)
    {
      while( *s==' ' )
        memmove(s,s+1,strlen(s));
      return s;
    }

  8. #8
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Code:
    sscanf( str, "%[^ ]", str1 );
    This could be your alternative.

    ssharish
    Life is like riding a bicycle. To keep your balance you must keep moving - Einstein

  9. #9
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by BillyTKid View Post
    Code:
    char *rtrim(char *s)
    {
      while( *s && s[strlen(s)-1]==' ' )
        s[strlen(s)-1]=0;
      return s;
    }
    
    char *ltrim(char *s)
    {
      while( *s==' ' )
        memmove(s,s+1,strlen(s));
      return s;
    }
    The ltrim function looks good, but why are you moving the whole string multiple times?

    Code:
    void ltrim(char *s)
      { char *t = s;
         while( *t ==' ')
            t++;
        memmove(s,t,strlen(t)+1); }
    The same with the rtrim function you only need 1 null terminator.

    Code:
    void rtrim(char *s)
      { int n;
         for (n=strlen(s); n>0; n--)
            if (s[n] != ' ')
              { s[n+1]='\0'; 
                 return; } }
    Last edited by CommonTater; 12-03-2010 at 04:02 PM. Reason: fixed second example

  10. #10
    Registered User
    Join Date
    Nov 2010
    Location
    xian china
    Posts
    31
    Code:
    void rtrim (char * s ) {
      int end;
      end = strlen(s) - 1;
      while(end >= 0 && s[end] == ' ')
      {
          end--;
      }
      if(end>=0 && s[end]!=' ')
      {
         s[end] = '\0';
      }
    }

  11. #11
    Registered User
    Join Date
    May 2010
    Location
    Naypyidaw
    Posts
    1,314
    @ jesius, in case if you didn't read post#6.

    monk64, there is a slight problem with your rtrim function though. strlen() returns a size_t, which is an unsigned integer type. This means that strlen(s) - 1 on an empty string would not produce a negative value. In fact, it would result in a value that probably is not in the range of an int. Furthermore, it seems that all you are doing is removing a trailing newline character, if it exists, rather than removing trailing spaces.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Inheritance Hierarchy for a Package class
    By twickre in forum C++ Programming
    Replies: 7
    Last Post: 12-08-2007, 04:13 PM
  2. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  3. RicBot
    By John_ in forum C++ Programming
    Replies: 8
    Last Post: 06-13-2006, 06:52 PM
  4. Calculator + LinkedList
    By maro009 in forum C++ Programming
    Replies: 20
    Last Post: 05-17-2005, 12:56 PM
  5. Replies: 3
    Last Post: 12-03-2001, 01:45 PM