2
char testStr[] = "          trim this           ";
char** pTestStr = &testStr;
trim(pTestStr);

int trim(char** pStr)
{
 char* str = *pStr;
 while(isspace(*str)) {
  (*pStr)++;
  str++;
 }

 if(*str == 0) {
  return 0;
 }

 char *end = str + strlen(str) - 1;
 while(end > str && isspace(*end))
  end--;
 *(end+1) = 0;

 return 0;
}
theanine
  • 986
  • 3
  • 10
  • 21
  • Duplicate: http://stackoverflow.com/questions/122616/painless-way-to-trim-leading-trailing-whitespace-in-c – indiv Jun 17 '10 at 19:37

3 Answers3

5

You need to make testStr writeable:

char testStr[] = "          trim this           ";

The problem is that char *ptr = ... has ptr pointing to the actual literal string which is in read-only memory.

By using char testStr[] = ... you are allocating an array and having the array initialized with the same contents as the literal string. Since this is an array, it is writable.

R Samuel Klatchko
  • 74,869
  • 16
  • 134
  • 187
  • I get: cannot convert parameter 1 from 'char (*)[38]' to 'char **' – theanine Jun 14 '10 at 17:37
  • @user364100 - no you can't. You'll want to change your function to `char* trim(char* pStr)` and then return the pointer to the first non-whitespace character. – R Samuel Klatchko Jun 14 '10 at 20:23
  • I don't want that. I want a trim function that trims in place. – theanine Jun 15 '10 at 20:26
  • @user364100 - it's still doing it in place. The question is whether you modify the input parameter or return a new value. – R Samuel Klatchko Jun 15 '10 at 21:17
  • Yes, I'd like to pass a pointer to the string, and move that pointer to reflect what's been trimmed off the left. Adding the null terminator to right-trim is easy enough. – theanine Jun 16 '10 at 00:38
  • @user364100 - you can't change the place in memory an array references and you can't modify the contents of a literal string. You could move to the heap but that brings a different set of issues. Accept the limitations of the language and work with them. – R Samuel Klatchko Jun 16 '10 at 04:55
2
char testStr[] = "          trim this           ";
char* pTestStr = &testStr[0];
trim(&pTestStr);

void trim(char* str)
{
    if(!str)
        return;

    char* ptr = str;
    int len = strlen(ptr);

    while(len-1 > 0 && isspace(ptr[len-1]))
        ptr[--len] = 0;

    while(*ptr && isspace(*ptr))
        ++ptr, --len;

    memmove(str, ptr, len + 1);
}
theanine
  • 986
  • 3
  • 10
  • 21
0

Edit : updated the code based on the latest version of zString library.

Below is my implementation for trim, left-trim and , right-trimfunctions (will be added to zString string library).

Although the functions return *char, since the original string is modified, these would serve your purpose.

One could use standard library functions, such as isspace(), but implementations below are bare bone code, that relies on no library function.

/* trim */
char *zstring_trim(char *str){
    char *src=str;  /* save the original pointer */
    char *dst=str;  /* result */
    char c;
    int is_space=0;
    int in_word=0;  /* word boundary logical check */
    int index=0;    /* index of the last non-space char*/

    /* validate input */
    if (!str)
        return str;

    while ((c=*src)){
        is_space=0;

        if (c=='\t' || c=='\v' || c=='\f' || c=='\n' || c=='\r' || c==' ')
            is_space=1;

        if(is_space == 0){
         /* Found a word */
            in_word = 1;
            *dst++ = *src++;  /* make the assignment first
                               * then increment
                               */
        } else if (is_space==1 && in_word==0) {
         /* Already going through a series of white-spaces */
            in_word=0;
            ++src;
        } else if (is_space==1 && in_word==1) {
         /* End of a word, dont mind copy white spaces here */
            in_word=0;
            *dst++ = *src++;
            index = (dst-str)-1; /* location of the last char */
        }
    }

    /* terminate the string */
    *(str+index)='\0';

    return str;
}

/* right trim */
char *zstring_rtrim(char *str){
    char *src=str;  /* save the original pointer */
    char *dst=str;  /* result */
    char c;
    int is_space=0;
    int index=0;    /* index of the last non-space char */

    /* validate input */
    if (!str)
        return str;

    /* copy the string */
    while(*src){
        *dst++ = *src++;
        c = *src;

        if (c=='\t' || c=='\v' || c=='\f' || c=='\n' || c=='\r' || c==' ')
            is_space=1;
        else
            is_space=0;

        if (is_space==0 && *src)
            index = (src-str)+1;
    }

    /* terminate the string */
    *(str+index)='\0';

    return str;
}

/* left trim */
char *zstring_ltrim(char *str){
    char *src=str;  /* save the original pointer */
    char *dst=str;  /* result */
    char c;
    int index=0;    /* index of the first non-space char */

    /* validate input */
    if (!str)
        return str;

    /* skip leading white-spaces */
    while((c=*src)){ 
        if (c=='\t' || c=='\v' || c=='\f' || c=='\n' || c=='\r' || c==' '){
            ++src;
            ++index;
        } else
            break;
    }

    /* copy rest of the string */
    while(*src)
        *dst++ = *src++;

    /* terminate the string */
    *(src-index)='\0';

    return str;
}
fnisi
  • 1,181
  • 1
  • 14
  • 24