1,105,395 Community Members

Implementing String trimming (Ltrim and Rtrim) in C

Member Avatar
(~s.o.s~)
Reputation Points: 2,496 [?]
Q&As Helped to Solve: 992 [?]
Skill Endorsements: 72 [?]
 
0
 

Here is a simple implementation of implementing a simple Left trim (ltrim) and Right trim(rtim) of unwanted characters from a C style string. (null terminated strings). Doesn't suffer the overheads of the memmove implementation in which the worst case scenario (a string containing all junk characters) is approx. N^2 / 2.

Comments, constructive criticisims are welcome.

#include <stdio.h>

char* rtrim(char* string, char junk);
char* ltrim(char* string, char junk);

int main()
{
    char testStr1[] = "     We like helping out people          ";
    char testStr2[] = "     We like helping out people          ";
    char testStr3[] = "     We like helping out people          ";
    printf("|%s|", testStr1);
    printf("\n|%s|", ltrim(testStr1, ' '));
    printf("\n\n|%s|", testStr2);
    printf("\n\n|%s|", rtrim(testStr2, ' '));
    printf("\n\n|%s|", testStr3);
    printf("\n|%s|", ltrim(rtrim(testStr3, ' '), ' '));
    getchar();
    return 0;
}


char* rtrim(char* string, char junk)
{
    char* original = string + strlen(string);
    while(*--original == junk);
    *(original + 1) = '\0';
    return string;
}

char* ltrim(char *string, char junk)
{
    char* original = string;
    char *p = original;
    int trimmed = 0;
    do
    {
        if (*original != junk || trimmed)
        {
            trimmed = 1;
            *p++ = *original;
        }
    }
    while (*original++ != '\0');
    return string;
}
/*

|     We like helping out people          |
|We like helping out people          |

|     We like helping out people          |

|     We like helping out people|

|     We like helping out people          |
|We like helping out people|

 */
Member Avatar
Nutty
Newbie Poster
1 post since May 2007
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

it is a good, i like this type of programe

Member Avatar
StrikerX
Newbie Poster
12 posts since Apr 2007
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

Nice one, thanks .

Member Avatar
Ene Uran
Posting Virtuoso
1,822 posts since Aug 2005
Reputation Points: 610 [?]
Q&As Helped to Solve: 278 [?]
Skill Endorsements: 10 [?]
 
0
 

How to you handle tabs?

Member Avatar
~s.o.s~
Failure as a human
10,399 posts since Jun 2006
Reputation Points: 2,496 [?]
Q&As Helped to Solve: 992 [?]
Skill Endorsements: 72 [?]
Administrator
Featured
 
0
 

> How to you handle tabs?
If you will notice, this is not a generic function, the way we have in Python, Ruby and other languages. You need to pass the character to be stripped. If you want to strip off tabs, pass the junk character to be '\t'.

Member Avatar
Melando
Newbie Poster
1 post since Nov 2011
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
1
 

Attention: rtrim could modify memory outside string range

Member Avatar
Narue
Bad Cop
12,139 posts since Sep 2004
Reputation Points: 5,693 [?]
Q&As Helped to Solve: 1,537 [?]
Skill Endorsements: 81 [?]
Team Colleague
 
2
 

Attention: rtrim could modify memory outside string range

While you're correct, the bug report is unhelpful because you haven't specified when this would happen or suggested a fix. The problem stems from an unchecked decrement of original , which can drop below string if it's empty of contains nothing but junk characters.

If whatever memory prior to string also contains junk characters, the loop will continue and modify memory outside the bounds of the array. If memory prior to string doesn't contain junk characters, at least one element beyond the array will be accessed, which is still undefined behavior.

Trimming away the entire string is the special case that needs to be considered here, with awareness of three potential cases at original[0]:

  • original[0] is '\0': The string was empty, so nothing needs to be done.
  • original[0] is junk : The string is trimmed to nothing and must end at original[0] .
  • original[0] neither '\0' nor junk : The string must end after original[0] , as in the original algorithm.

Once the potential cases are discovered, it's a simple matter to account for them:

char *rtrim(char *string, char junk)
{
    char *original = string + strlen(string);

    while (original != string && *--original == junk)
        ;
    
    if (*original != '\0')
        original[*original == junk ? 0 : 1] = '\0';

    return string;
}
NTNKMR
Newbie Poster
1 post since Oct 2013
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
Unverified Member
 
0
 
void ltrim(char str[PATH_MAX])
{
        int i = 0, j = 0;
        char buf[PATH_MAX];
        strcpy(buf, str);
        for(;str[i] == ' ';i++);

        for(;str[i] != '\0';i++,j++)
                buf[j] = str[i];
        buf[j] = '\0';
        strcpy(str, buf);
}
Member Avatar
Ancient Dragon
Achieved Level 70
27,632 posts since Aug 2005
Reputation Points: 5,232 [?]
Q&As Helped to Solve: 3,037 [?]
Skill Endorsements: 115 [?]
Team Colleague
Featured
Sponsor
 
0
 

Ntnkmr: Your version does too much work -- it's not necessary to use a temporary buffer. Once you find the first non-space character move all remaining characters to the beginning of the line.

Member Avatar
nonlinearly
Newbie Poster
9 posts since Dec 2010
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

Narue, your code always retunrs the same results... the returned parameter string does not change anywhere in the function

Member Avatar
Ancient Dragon
Achieved Level 70
27,632 posts since Aug 2005
Reputation Points: 5,232 [?]
Q&As Helped to Solve: 3,037 [?]
Skill Endorsements: 115 [?]
Team Colleague
Featured
Sponsor
 
0
 

The function is for right-trim, so the value of string will not change. All the function does is start at the end of string and work backwards until it finds the first non-junk character, then truncates string at that point.

Member Avatar
nonlinearly
Newbie Poster
9 posts since Dec 2010
Reputation Points: 0 [?]
Q&As Helped to Solve: 0 [?]
Skill Endorsements: 0 [?]
 
0
 

yes now I understand... but then it does not need to return anything because string is a pointer always to the same point...

Member Avatar
Ancient Dragon
Achieved Level 70
27,632 posts since Aug 2005
Reputation Points: 5,232 [?]
Q&As Helped to Solve: 3,037 [?]
Skill Endorsements: 115 [?]
Team Colleague
Featured
Sponsor
 
0
 

Yes, it doesn't have to return anything, but string functions often do so that the function can be nested inside other fuctions, for example

printf("%s\n", rtrim(somestring, ' '));

You
Post:
Start New Discussion
Tags Related to this Article