Thread: trim function - could you explain please

  1. #1
    Registered User
    Join Date
    Mar 2010
    Posts
    94

    Unhappy trim function - could you explain please

    /* trim: remove trailing blanks, tabs, newlines */
    int trim(char s[])
    {
    int n;
    for (n = strlen(s)-1; n >= 0; n--)
    if (s[n] != ' ' && s[n] != '\t' && s[n] != '\n')
    break;
    s[n+1] = '\0';
    return n;
    }

    from K&R

    With simple example like, string: "ker rit" or smthg similar.

    Thanks!

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Well, observe this:
    Code:
    n = strlen(s)-1
    So, n starts of as the index of the last character in the string.

    Now, look at:
    Code:
    n >= 0; n--
    So, if nothing stops the loop early, the loop index will decrease until it is the index of the first character in the string, and then when it is less than that, the loop will end.

    Now, in the loop we see:
    Code:
    if (s[n] != ' ' && s[n] != '\t' && s[n] != '\n')
        break;
    Thus, control will break out of the loop if the current character does not match any of ' ', '\t' and '\n'.

    After the loop, this:
    Code:
    s[n+1] = '\0';
    causes the last detected character that matched ' ', '\t' or '\n' to be replaced by a null character, effectively trimming the string to remove trailing whitespace. (If there is no such character, we can reason that this will just replace the null character with a null character, with no net effect.)
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Here is what the function does, let's take an example:

    Let s[] = "this is a string \t \n"

    the string contains "this is a string" plus 3 additional trailing white spaces, one tab character and one endline character.

    The function starts iterating from the end of the string and goes backwards towards the beginning. When it finds character that is a space, a tab or an endline it keeps moving one position towards the beginning. When it finally finds a character that is NOT a trailing space, tab or endline it marks THE NEXT character ( the character that it just verified in the previous iteration as the nul terminator, therefore shortening the string and removing the spaces.

    Here is how the for loop works on our example s.

    Iteration 1)

    n = strlen(s) - 1 --> we are checking s[n] which is the \n endline character.
    (Obviously \n is an endline so the for continues)

    Iteration 2)
    n = strlen(s) - 2 --> we are checking the s[n] which is the tab \t character.
    (Obviously \t is a tab so the for continues)

    Iteration 3)
    n = strlen(s) - 3 --> we are checking the s[n] which is the last of the three trailing whitespaces ' ' just before the tab \t
    (Obviously ' ' is a whitespace so the for continues)

    Iteration 4)
    n = strlen(s) - 4 --> we are checking the s[n] which is the middle whitespace.
    (Obviously ' ' is a whitespace so the for continues)

    Iteration 5)
    n = strlen(s) - 5 --> we are checking the s[n] which is the first whitespace
    (Obviously ' ' is a whitespace so the for continues)

    Iteration 6) --- last one
    n = strlen(s) - 6 --> we are checking s[n] which is the letter 'g' from the word string
    Finally, the if condition is true. 'g' is not a space a tab or an endline so the break instruction executes and we exit the loop.

    At this point n = strlen(s) -6

    We set s[n+1], in other words s[strlen(s) -5] to the string terminator overwriting the first whitespace with '\0'. As a result all the trailing characters are removed and the string is now shorter.

  4. #4
    Registered User
    Join Date
    Mar 2010
    Posts
    94
    Thank you both! But let me also mention that your example was quite clear claudiu.

  5. #5
    Registered User
    Join Date
    Mar 2010
    Posts
    94
    One thing I cannot understand this function is returning n and how come this will lead to -> "As a result all the trailing characters are removed and the string is now shorter."

    Thanks!

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by c_lady
    One thing I cannot understand this function is returning n and how come this will lead to -> "As a result all the trailing characters are removed and the string is now shorter."
    It is the assignment of '\0' to s[n+1] that shortens the string.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Mar 2010
    Posts
    94
    Thanks!

  8. #8
    Registered User
    Join Date
    Mar 2010
    Posts
    94
    Do you have any suggestion where I can read more about break and continue? Something useful I mean as I know also to Google -)

  9. #9
    Registered User
    Join Date
    Mar 2010
    Posts
    94
    Neither break nor continue has any effect on a brace-enclosed block of statements following an if. break causes a break out of the innermost switch or loop, and continue forces the next iteration of the innermost loop.

    Can someone explain these sentences?

  10. #10
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Ok basically here are two examples one illustrating the use of break and one illustrating the use of continue:

    Code:
    int i,j;
    for(i = 0;i < 10;i++){
     for(j = 0;j < 10;j++){
       if(i + j == 17) break;
     }
     /* on break control is returned here, just outside the innermost loop */
    }
    In the code above you have two simple nested for loops. When the condition inside the second for is true, control is returned right outside the innermost loop but inside the first one. (i.e. the i loop)

    Code:
    int i,j;
    for(i = 0;i < 10;i++){
     for(j = 0;j < 10;j++){
       /* on continue control is returned here, after the loop variable has already been incremented 
           THE LOOP INDEX IS ONLY INCREMENTED AUTOMATICALLY IN FOR LOOPS */
       if(i % j != 0) continue;
     }
    }
    In short, break stands for Break from this loop and continue stands for continue the loop with the next iteration immediately, thus ignoring any additional instructions after the continue, inside the loop.

    As an exercise try to come up with a similar example where you have a continue inside a single while loop. See what the difference is.
    Last edited by claudiu; 03-27-2010 at 06:50 AM.

  11. #11
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Also, note that you are most likely going to use break a lot more than continue while programming.

  12. #12
    Registered User
    Join Date
    Mar 2010
    Posts
    94
    #include <stdio.h>
    main(){
    int i;
    for(i=0; i<10; i++){
    if(i%2==0)
    continue;
    printf("%d ", i);
    }
    }
    1 3 5 7 9 ... correct?

  13. #13
    Registered User claudiu's Avatar
    Join Date
    Feb 2010
    Location
    London, United Kingdom
    Posts
    2,094
    Quote Originally Posted by c_lady View Post
    #include <stdio.h>
    main(){
    int i;
    for(i=0; i<10; i++){
    if(i%2==0)
    continue;
    printf("%d ", i);
    }
    }
    1 3 5 7 9 ... correct?
    Yes, you got it.

  14. #14
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    30 posts and you still don't get the use of code tags?

    Yeah, you'll do well in this field.

  15. #15
    Registered User
    Join Date
    Mar 2010
    Posts
    94
    Thanks2YourHelp!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Compiling C in Visual Studio 2005
    By emanresu in forum C Programming
    Replies: 3
    Last Post: 11-16-2009, 04:25 AM
  2. dllimport function not allowed
    By steve1_rm in forum C++ Programming
    Replies: 5
    Last Post: 03-11-2008, 03:33 AM
  3. Change this program so it uses function??
    By stormfront in forum C Programming
    Replies: 8
    Last Post: 11-01-2005, 08:55 AM
  4. const at the end of a sub routine?
    By Kleid-0 in forum C++ Programming
    Replies: 14
    Last Post: 10-23-2005, 06:44 PM
  5. Replies: 5
    Last Post: 02-08-2003, 07:42 PM