Trim a string in C

Left trim

To left trim a string, find the length of prefix containing the characters to trim with strspn(), and then move the rest of the string forwards on top of it with memmove(), not forgetting to move the terminating nul character. Note that checking for the prefix being greater than zero will cover the case where the string is empty.

char *ltrim(char *str, const char *seps)
{
    size_t totrim;
    if (seps == NULL) {
        seps = "\t\n\v\f\r ";
    }
    totrim = strspn(str, seps);
    if (totrim > 0) {
        size_t len = strlen(str);
        if (totrim == len) {
            str[0] = '\0';
        }
        else {
            memmove(str, str + totrim, len + 1 - totrim);
        }
    }
    return str;
}

Right trim

To right trim, scan the string from the right and replace any characters to trim with nul characters, until you find a character you want to keep or you run out of string.

char *rtrim(char *str, const char *seps)
{
    int i;
    if (seps == NULL) {
        seps = "\t\n\v\f\r ";
    }
    i = strlen(str) - 1;
    while (i >= 0 && strchr(seps, str[i]) != NULL) {
        str[i] = '\0';
        i--;
    }
    return str;
}

Trim

To trim both ends of a string, just right trim it and then left trim it, or vice-versa.

char *trim(char *str, const char *seps)
{
    return ltrim(rtrim(str, seps), seps);
}

Test program

This tries all of the important cases with a space as the separator.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <trim.h>

size_t maxlen(char **strings, size_t len)
{
    unsigned int i;
    size_t max = 0;
    for (i = 0; i < len; i++) {
        if (strlen(strings[i]) > max) {
            max = strlen(strings[i]);
        }
    }
    return max;
}

int main(void)
{
    char *strings[] = {"", " ", "  " "test", " test", "test ", " test ",
        "  test", "test  ", "  test  "};
    const size_t n = sizeof(strings) / sizeof(char *);
    unsigned int i;
    char *str = malloc(maxlen(strings, n) + 1);
    for (i = 0; i < n; i++) {
        strcpy(str, strings[i]);
        trim(str, NULL);
        printf("%s\n", str);
    }
    free(str);
    return 0;
}