Thread: trim string function (code)

  1. #1
    Registered User
    Join Date
    Jan 2003
    Posts
    52

    trim string function (code)

    Hi all! I coded this function to eliminate spaces before and after a string.
    e.g.:
    Code:
    trim("       just a test    123      ");
    will return
    Code:
    "just a test    123"
    But I didn't uderstand why the compiler ask for *trim instead of trim.
    Any improvement/suggestion is welcome.


    Code:
    char *trim(char string[100])
    {
    	int a, b, c, d; 
    	char trimed_string[100];
    	a = b = c = d = 0;
    	
    	for (a; a < strlen(string); a++)
    	{
    		if (string[a]!=' ' && !b) /* first valid char */
    			b = a;
    		if (string[a]==' ' && b)
    		{
    			for (d; d < strlen(string)-a;d++)
    				if (string[d+a]!=' ')
    					c = a+d;
    		}
    	}
    
    	a=0;
    	for (b; b <= c; b++)
    	{
    		trimed_string[a]= string[b];
    		a++;
    	}
    	trimed_string[ strlen(trimed_string)-10 ] ='\0'; // why -10 ? otherwise it'll return junk
    	return(trimed_string);
    }

  2. #2
    Registered User
    Join Date
    Jan 2003
    Posts
    52
    I just tested with another string and there's something wrong with this line:
    Code:
    trimed_string[ strlen(trimed_string)-10 ] ='\0';
    output of
    Code:
    trim("    test12      3  3     4   ")
    Code:
    test12      3  3     4Ûw╗hÛ
    There's something wrong with the string termination '\0';

  3. #3
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    Your code is entirely too complicated for the task at hand, and it's also incorrect. You get garbage when you return because you cannot return a pointer to a local variable, so trimed_string is off limits for a return value. A simpler solution would be to find the first non-space index, the last non-space index, and copy that slice to the beginning of the string. Terminate with a nul and you're done:
    Code:
    char *tr ( char *s )
    {
      int i = 0;
      int j = strlen ( s ) - 1;
      int k = 0;
    
      while ( isspace ( s[i] ) && s[i] != '\0' )
        i++;
    
      while ( isspace ( s[j] ) && j >= 0 )
        j--;
    
      while ( i <= j )
        s[k++] = s[i++];
    
      s[k] = '\0';
    
      return s;
    }
    -Prelude
    My best code is written with the delete key.

  4. #4
    Registered User
    Join Date
    Jan 2003
    Posts
    52
    you function is better.
    but I still not understand why my function returned junk after the string.

  5. #5
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >but I still not understand why my function returned junk after the string.
    Code:
    char *f()
    {
      /* Memory is allocated for the local array a */
      char a[] = "Some string";
    
      /* The address of a is returned to the caller */
      return a;
    }
    /* After f returns the memory for a is reclaimed. */
    
    int main ( void )
    {
      char *p = f();
      /* Since the memory for a was reclaimed, p now points to released memory */
    
      return 0;
    }
    -Prelude
    My best code is written with the delete key.

  6. #6
    Registered User
    Join Date
    Dec 2002
    Posts
    20
    how about strtok.

    char *tokchar;
    tokchar = strtok(trim_string, " ");
    while(tokchar != NULL){

    printf////////

    tokchar = strtok(NULL, " ");
    }

  7. #7
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >how about strtok.
    That won't work as you would expect if there are internal spaces. The original question was about removing leading and trailing whitespace while leaving everything else intact.

    -Prelude
    My best code is written with the delete key.

  8. #8
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231

    Re: trim string function (code)

    >>trim(" just a test 123 ");
    Don't forget, you cannot safely modify the data passed in by this function call, as its a string literal.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  9. #9
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Here's yet another example:

    Code:
    char * normalize(char * string){
     char * s, * i;
     int ready = FALSE;
     
        for(i = s = string; *i; ++i)
       {
    
           if(isspace(*i))
          {
              if(!ready)
             {
              continue;
             }
              else ready = FALSE;
          }
           else ready = TRUE;
    
        *(s++) = *i;
       }
    
     *s = 0;
     return string;
    }
    
    
    
    
    
    
    
    int main(){
     char string[] = "   I        think,    therefore    I          am.";
     printf("Before:\n%s\n",string);
     printf("After:\n%s", normalize(string));
     getch();
     return 0;
    }
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  10. #10
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    if(isspace(*i))
    {
        if(!ready)
        {
            continue;
        }
        else ready = FALSE;
    }
    else ready = TRUE;
    There is no need for the continue.

    Code:
    ready = isspace(*i) ? FALSE ? TRUE;
    Or drawn out...
    Code:
    if( isspace(*i) )
        ready = FALSE;
    else
        ready = TRUE;
    There really is no need to check the ready state once you do the isspace() check, since either way, if it is a space, ready gets set to FALSE. So just do it in one step.

    Speed wise, this is probably faster anyway:
    Code:
    check isspace
        check ready state
            continue
        else check ready state
            ready = FALSE
    else isspace
        ready = TRUE;
    1 check 1 assignment OR 2 checks 1 assignment

    Versus:
    Code:
    check isspace
        ready = FALSE
    else isspace
        ready = TRUE
    1 check, 1 assignment every time through.

    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  2. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  3. <Gulp>
    By kryptkat in forum Windows Programming
    Replies: 7
    Last Post: 01-14-2006, 01:03 PM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  5. help with a source code..
    By venom424 in forum C++ Programming
    Replies: 8
    Last Post: 05-21-2004, 12:42 PM