Thread: strend(s,t) from K&R C

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    3

    Question strend(s,t) from K&R C

    I've begun to delve the deep wisdom of K&R and resolved to complete each of the exercises presented therein.

    Now, I have a working example of exercise 5-4, which asks you to "Write the function strend(s, t), which returns 1 if the string t occurs at the end of the string s, and zero otherwise."

    If anyone has any constructive criticism to offer on the composition of my code, it would be much appreciated.

    I've included main() for convenience.

    Code:
    #include <stdio.h>
    
    int strend(char *s, char *t);
    
    #define SIZE 16
    
    int main() {
    	char helloWorld[SIZE] = "Hello world!";
    	char justWorld[SIZE] = "world!";
    	
    	if (strend(helloWorld, justWorld))
    		printf("justWorld occurs at the end of helloWorld\n");
    	else
    		printf("justWorld DOES NOT occur at the end of helloWorld\n");
    	return 0;
    }
    
    int strend(char *s, char *t) {
    	while (*s++) {	
    		if (*t == *s) {
    			while ((*s++ == *t++) && (*t != '\0')) ;
    			if (*s == '\0' && *t == '\0')
    				return 1;
    			return 0;
    		}
    	}
    	return 0;
    }
    Thanks!

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Hmm. I'd be lazier.

    Code:
    int strend( const char *s, const char *t )
    {
        int ns = strlen(s), nt = strlen(t);
        return nt <= ns && strcmp( s + ns - nt, t ) == 0;
    }
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    There's one problem with your code that I can see [edit](by "your" I mean danthehat)[/edit]: consider a string like "endendend", and an ending of "endend". I don't think your code would "spot" the ending, since it would stumble across another substring that starts with the same thing.

    Just a thought:
    Code:
    /**
        @return True if @a string ends with @a ending.
    */
    int strend(char *string, char *ending) {
        char *ending_end = ending;
        char *string_start = string + strlen(string);
        
        while(string_start != string && *ending_end) {
            string_start --;
            ending_end ++;
        }
    
        /* The string isn't long enough to contain ending. */
        if(*ending_end) return 0;
    
        while(*string_start && *string_start == *ending) {
            string_start ++;
            ending ++;
        }
    
        return *string_start == 0;
    }
    I haven't tested it, but that code is supposed to step backwards from the end of the string strlen(ending) characters, and if the string isn't long enough return immediately. It then steps forwards in the string, making sure the string matches ending.

    There are probably more efficient ways of doing this, but that's what came to mind first. (Actually, there *are* more efficient ways of doing this, I just thought of one. Sigh. See if you can improve on it.)
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  4. #4
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Just my 2c, but IMO it's better to start at the right end of both the arrays instead of their left end (base of the arrays).
    Last edited by itCbitC; 05-07-2009 at 01:07 PM.

  5. #5
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    and here's my version of strend():
    Code:
    int strend(char *s, char *t, int i)
    {
            while (i-- >= 0)
                if (*t-- != *s--)
                    return 0;
            return 1;
    }
    but with a minor modification to the way strend() is being called from main(), as in
    Code:
    if (strend(s+strlen(s)-1, t+strlen(t)-1, strlen(t)-1))

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    but with a minor modification to the way strend() is being called from main()
    That sounds like a major modification to me, and considering that your version of strend() is so different from the requirements, it basically... is not strend.

    EDIT:
    After some eyeballing of code and consideration of alternatives, I think that brewbuck's solution (and other equivalents) is likely to be the best.
    Last edited by laserlight; 05-07-2009 at 01:46 PM.
    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
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    That sounds like a major modification to me, and considering that your version of strend() is so different from the requirements, it basically... is not strend.
    fail to see where the endianness has been specified.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    fail to see where the endianness
    So, you insist that s+strlen(s)-1 is the string s, and t+strlen(t)-1 is the string t, and you can add a parameter at will? That is a fine way to do software development: the requirements are there to be ignored.

    Anyway, what you can do is easy: just turn your function into a helper function.

    EDIT:
    Oh, but then your function has a bug: it assumes that the length of t is never greater than the length of s.

    EDIT #2:
    Okay, that is not quite true. More accurately, the example of the call of your function has a bug. It should pass the length of the shorter of the two strings as the third argument.
    Last edited by laserlight; 05-07-2009 at 01:57 PM.
    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

  9. #9
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    So, you insist that s+strlen(s)-1 is the string s, and t+strlen(t)-1 is the string t, and you can add a parameter at will? That is a fine way to do software development: the requirements are there to be ignored.

    Anyway, what you can do is easy: just turn your function into a helper function.
    Nope, I don't insist on going against requirements but pls point out where have the requirements been explicitly stated.

    Edit #1: yes robust error checking has been left out as an exercise for the reader

    Edit #2: what is a helper function (??), do you mean as in a library function.
    Last edited by itCbitC; 05-07-2009 at 02:01 PM.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    Nope, I don't insist on going against requirements but pls point out where have the requirements been explicitly stated.
    In post #1, and I quote: "Write the function strend(s, t), which returns 1 if the string t occurs at the end of the string s, and zero otherwise."
    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

  11. #11
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    In post #1, and I quote: "Write the function strend(s, t), which returns 1 if the string t occurs at the end of the string s, and zero otherwise."
    Yep! I see your point, the title implies that strend() takes two char* parameters.

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itCbitC
    what is a helper function (??), do you mean as in a library function.
    No, I mean as a function whose primary purpose is to implement strend() (or more generally: a function intended as implementation detail of some set of functions that you are writing).
    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

  13. #13
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Quote Originally Posted by laserlight View Post
    No, I mean as a function whose primary purpose is to implement strend() (or more generally: a function intended as implementation detail of some set of functions that you are writing).
    Alright! I see you mean as an intermediate step in the processing.
    So here's my attempt at the true-to-requirements function:
    Code:
    int strend(char *s, char *t)
    {
            int i = strlen(t)-1;
            int j = strlen(s)-1;
            char *es = s+j;
            char *et = t+i;
    
            while (i-- >= 0)
                if (*et-- != *es--) return 0;
            return 1;
    }
    Last edited by itCbitC; 05-07-2009 at 02:17 PM.

  14. #14
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    int strend( char *s, char *t )
    {
        size_t slen = 0;
        size_t tlen = 0;
    
        for( slen = 0; s[slen]; slen++ );
        for( tlen = 0; t[tlen]; tlen++ );
    
        /*
         *  Pick one:
         *
        for( slen -= tlen; tlen && (s + slen)[tlen] == t[tlen]; tlen-- );
         *
        while( tlen && s[slen--] == t[tlen--] );
         */
    
        return !!tlen;
    }
    Sans error checking.


    Quzah.
    Last edited by quzah; 05-07-2009 at 03:27 PM. Reason: Options are always fun.
    Hope is the first step on the road to disappointment.

  15. #15
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The reason I like my solution is because A) it's clear what is happening and B) it does no unnecessary work. There is no getting around the fact that you have to find the ends of both strings (two calls to strlen) and there's no getting around the fact that you have to compare the overlap (one call to strcmp).
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. K&R solution?
    By deadhippo in forum C Programming
    Replies: 12
    Last Post: 05-09-2008, 06:36 AM
  2. K&R book help
    By HLA91 in forum C Programming
    Replies: 4
    Last Post: 04-17-2008, 03:12 PM
  3. Help with K&R Book Exercise
    By Alejandrito in forum C Programming
    Replies: 5
    Last Post: 03-11-2008, 01:24 PM
  4. Line Counting Help (K&R)
    By smittles2003 in forum C Programming
    Replies: 9
    Last Post: 01-05-2007, 04:00 PM
  5. K&R question
    By tcpl in forum C Programming
    Replies: 10
    Last Post: 03-12-2006, 07:07 PM