Search code examples
cpointersdynamic-memory-allocation

Return a trimmed string using pointers


I'm trying to trim a string (remove white spaces from the start & end of the string) using pointers for that.

char* killspace(char *a)
{
    char *enda = NULL;
    int i = 0, spaceS = 0, spaceE = 0, bigend = 0 , out = 0, taille = strlen(a); 
    do
    {
        if (a[i] == ' ')
        {
            spaceS++;   
        }
        else
        {
            out = 1;
        }
        i++;
    } while (out == 0);
    out = 0;
    do
    {
        if (a[taille] == ' ')
        {
            spaceE++;
        }
        else
        {
            out = 1;
        }
        taille--;
    } while (out == 0);
    bigend = (spaceE + spaceS);
    // new size
    enda = (char *)calloc((strlen(a)-bigend), sizeof(char));
    i = 0;
    for (int j = spaceS; j < (strlen(a)-spaceE); j++)
    {
        enda[i] = a[j];
        i++;
    }
    return(enda);
    free(enda);
    
}

bigend is the number of whitespaces at the beginning and at the end of the string.

but the returned result had some random char like "ýýýý««««««««îþîþîþ"


Solution

  • Changing the beginning address to a string, requires either (1) sending the address to the pointer holding the string as an argument so it can be changed or (2) returning a pointer to the new beginning of the trimmed string from the function. The latter is probably your best bet. Here is an example:

    #include <stdio.h>
    #include <ctype.h>
    
    char *trimstr (char *s)
    {
        while (isspace(*s))     /* while space, increment pointer   */
            s++;
    
        char *p = s;            /* pointer to string s              */
        while (*p) p++;         /* advance pointer to end of s      */
        p--;                    /* decrement pointer off null-term  */
    
        while (isspace(*p))     /* while space, set new end of str  */
        {
            *p = 0;
            p--;
        }
    
        return s;               /* return pointer to trimmed string */
    }
    
    int main () {
    
        char mystring[] = "  some string with leading/trailing WS  ";
        char *p = mystring;
    
        printf ("\n  Original String: '%s'\n\n", mystring);
    
        p = trimstr (mystring);
    
        printf ("  Trimmed String : '%s'\n\n", p);
    
        return 0;
    }
    

    output:

    $ ./bin/trimstr
    
      Original String: '  some string with leading/trailing WS  '
    
      Trimmed String : 'some string with leading/trailing WS'
    

    Approaching the problem this way generally results in shorter code that trying to do the "index-shuffle" to move all characters downward in the string to cover the leading whitespace. However, there is nothing wrong with the "index-shuffle", you just have to be particular with the offset and remember to also offset the null-terminator.

    If you are interested in saving lines of code, a more compact, albeit slightly less-readable version of the trimstr function can be written as follows:

    char *trimstr (char *s)
    {
        while (isspace(*s)) s++;        /* while space, increment pointer   */
        char *p = s;                    /* pointer to string s              */
        while (*p) p++;                 /* advance pointer to end of s      */
        while (isspace(*(--p))) *p = 0; /* while space, set new end of str  */
        return s;                       /* return pointer to trimmed string */
    }