Thread: word reverser

  1. #1
    Registered User
    Join Date
    Dec 2003
    Posts
    8

    word reverser

    Hi
    I'm writing a program to reverse words. When I input, say, "they call me jim" I get this:

    fjim
    fmefcallthey

    instead of this:
    jim me call they

    So I'm not exactly sure where the 'f' is coming from, and where the newline is coming from. I guess I'm kinda confused here. I can't really think of a good reason why the 'f's' should be there. Thanks for any help you can give me.
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
      char buffer[30];
      int i, count;
      printf("enter a string: \n");
      fgets(buffer, 29, stdin);
      i = strlen(buffer) - 1;
      while (i > -1)
        {
          if ((buffer[i] == ' ') && (buffer[i] != '\0'))
    	{
    	  putc(" ", stdout);
    	  count = i - 1;
    	  i++;
    	  while ((buffer[i] != ' ') && (buffer[i] != '\0'))
    	    {
    	      putc(buffer[i], stdout);
    	      i++;
    	    }
    	  i = count;
    	}
          
          else
    	i--;
        }
    
      for (i = 0; buffer[i] != ' '; i++)
        {
          putc(buffer[i], stdout);
        }
    
      return 0;
    }

  2. #2
    & the hat of GPL slaying Thantos's Avatar
    Join Date
    Sep 2001
    Posts
    5,681
    Not sure on the f thing yet but a couple of points:

    Code:
    char buffer[30];
    fgets(buffer, 29, stdin);
    fgets will get the length specified minus one. So if you specify 29 it will get 28.

    You should check the return of fgets() for error checking.

    To get rid of the newline problem add:
    Code:
    if ( buffer[strlen(buffer)-1] == '\n' )
      buffer[strlen(buffer)-1] = '\0';
    after the fgets() call

    Oh found this while compiling:

    fputc(" ", stdout);
    should be
    fputc(' ', stdout);
    Last edited by Thantos; 03-26-2004 at 08:00 PM.

  3. #3
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    I believe your problem is here
    Code:
    putc(" ", stdout);
    [edit]

    You are too quick on the draw Thantos - beat me to it.

    [/edit]

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    void revword( char * s )
    {
        if( s && *s )
        {
            revword( s+1 );
            putchar( *s );
        }
    }
    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Dec 2003
    Posts
    8
    Got it. Thanks all.

  6. #6
    Registered User
    Join Date
    Feb 2004
    Posts
    72
    Originally posted by quzah
    Code:
    void revword( char * s )
    {
        if( s && *s )
        {
            revword( s+1 );
            putchar( *s );
        }
    }
    Quzah.
    Beware of this code.

    Rather than reversing the words ("they call me jim" -> "jim me call they") it will reverse the whole string ("they call me jim" -> "mij em llac yeht") which given the original problem doesn't sound like what's needed.

  7. #7
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Originally posted by major_blagger
    it will reverse the whole string ("they call me jim" -> "mij em llac yeht") which given the original problem doesn't sound like what's needed.
    It's not my fault if you don't call the function right. That's like saying tolower is bad because you expect it to actually modify the passed variable and lower case it or something. Or it's like saying "Beware of arrays! You can run past the end of them and C won't stop you!" It's simply a tool. It's your job to use it right.

    The code does exactly what it was written to do. It's not my fault if you call it incorrectly, nor does it make it bad code.

    A fine example is scanf. People call it wrong here all the time:
    Code:
    int x;
    
    scanf("%d", x );
    Does it make it bad code because you called it wrong? Is it now something to beware?

    Besides, it's simply here for my amusement. I usually don't hand you "the optimal response for optimal class room grade". I provide something interesting and different.

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

  8. #8
    Registered User
    Join Date
    Feb 2004
    Posts
    72
    Originally posted by quzah
    It's not my fault if you don't call the function right. That's like saying tolower is bad because you expect it to actually modify the passed variable and lower case it or something. Or it's like saying "Beware of arrays! You can run past the end of them and C won't stop you!" It's simply a tool. It's your job to use it right.

    The code does exactly what it was written to do. It's not my fault if you call it incorrectly, nor does it make it bad code.

    Does it make it bad code because you called it wrong? Is it now something to beware?

    Quzah.
    I wouldn't dare suggest it was bad code. I was only helping out the original poster and anyone trying to learn from this thread that they should take care in understanding that the function is not a solution to the posted question. I tried to provide some explanation of what it did.

    And yes, I consider it good advice to take care with arrays in C. Running past the end is a common bug.

  9. #9
    Been here, done that.
    Join Date
    May 2003
    Posts
    1,164
    Originally posted by quzah
    A fine example is scanf. People call it wrong here all the time:
    Code:
    int x;
    
    scanf("%d", x );
    Does it make it bad code because you called it wrong? Is it now something to beware?
    Yes.
    Definition: Politics -- Latin, from
    poly meaning many and
    tics meaning blood sucking parasites
    -- Tom Smothers

  10. #10
    The C-er
    Join Date
    Mar 2004
    Posts
    192
    Quzah, I would suggest your code is bad, the code itself is fine, but it does not conform to specification, and so leads one to think that it addresses the problem raised in the original post.

    I guess If you released formal documentation and specifications, then I might let you off this time. Just don't let me catch you doing it again.

  11. #11
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Jez
    Quzah, I would suggest your code is bad, the code itself is fine, but it does not conform to specification, and so leads one to think that it addresses the problem raised in the original post.
    Well, you'd be wrong. It does conform to the specifications.
    Code:
    char * word( char * s )
    {
        int x = 0;
        static char buf[BUFSIZ] = {0};
        memset( buf, 0, BUFSIZ );
    
        while( s && *s && isspace( *s ) ) s++;
        while( s && *s && !isspace( *s ) && x < BUFSIZ-1 ) buf[x++] = *s++;
        return buf;
    }
    
    void revword( char * s )
    {
        if( s && *s )
        {
            revword( s+1 );
            putchar( *s );
        }
    }
    int main( void )
    {
        char *foo = "hello there";
        char *bar = foo;
        int length = 0;
    
        do
        {
            bar = word( foo + length );
            length += strlen( bar );
            revword( bar );
        } while( bar && *bar );
        return 0;
    }
    Quick hack, it doesn't take spaces into account due to my quick throw together of the "word" function, but the point is, it, the revword function does conform to their description. It is not however, a all-in-one tool. It is one tool in a set of tools that would do the job exactly as they require, if they put the time in to do it.

    And as I've already stated, it was merely showing an alternative method for reversing a word. And it does work. I've just shown it works.

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

  12. #12
    Registered User
    Join Date
    Feb 2004
    Posts
    72
    Quote Originally Posted by quzah
    Well, you'd be wrong. It does conform to the specifications.

    And as I've already stated, it was merely showing an alternative method for reversing a word. And it does work. I've just shown it works.

    Quzah.
    Could you post your output for "they call me jim"?

  13. #13
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >And it does work.
    No, it doesn't. This could be because of your hackish solution as you say, but with the input "they call me jim", the output not only fails to be "jim me call they", it also fails to be a perfect reversal of the original string (with or without spaces). Try passing length as a reference parameter to word and update it in both loops. That would give you better results:
    Code:
    char * word( char * s, int * l )
    {
        int x = 0;
        static char buf[BUFSIZ] = {0};
        memset( buf, 0, BUFSIZ );
    
        while( s && *s && isspace( *s ) ) s++, (*l)++;
        while( s && *s && !isspace( *s ) && x < BUFSIZ-1 ) buf[x++] = *s++, (*l)++;
        return buf;
    }
    
    void revword( char * s )
    {
        if( s && *s )
        {
            revword( s+1 );
            putchar( *s );
        }
    }
    int main( void )
    {
        char *foo = "they call me jim";
        char *bar = foo;
        int length = 0;
    
        do
        {
            bar = word( foo + length, &length );
            revword( bar );
            putchar( bar[0] == '\0' ? '\n' : ' ' );
        } while( bar && *bar );
        return 0;
    }
    Or you could forgo recursion entirely and go with an in-place solution.
    Code:
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    
    void reverse ( char *s, int len )
    {
      int i, j;
    
      for ( i = 0, j = len - 1; i < j; i++, j-- ) {
        char save = s[i];
        s[i] = s[j];
        s[j] = save;
      }
    }
    
    void revword ( char *s )
    {
      while ( *s != '\0' ) {
        char *e = s;
        /* Find the end of a word */
        while ( *e != '\0' && !isspace ( *e ) )
          e++;
        reverse ( s, e - s );
        /* Find the next word */
        s = e;
        while ( *s != '\0' && isspace ( *s ) )
          s++;
      }
    }
    
    int main ( void )
    {
      char s[] = "they call me jim";
    
      reverse ( s, strlen ( s ) );
      revword ( s );
      puts ( s );
    
      return 0;
    }
    My best code is written with the delete key.

  14. #14
    Registered User pinko_liberal's Avatar
    Join Date
    Oct 2001
    Posts
    284
    Quote Originally Posted by Prelude
    >And it does work.
    it also fails to be a perfect reversal of the original string (with or without spaces)
    [/code]
    What do you mean by a perfect reversal?
    His program does spit out the characters in reverse order, or doesn't it?
    The one who says it cannot be done should never interrupt the one who is doing it.

  15. #15
    ... kermit's Avatar
    Join Date
    Jan 2003
    Posts
    1,534
    [edit]
    With regards to pinko_liberal's last post...
    [/edit]

    But does Quzah's program do this:

    <input> my name is Jim

    <output> mIJ si eman ym

    or this:

    <output> Jim is name my

    ??

    ~/
    Last edited by kermit; 03-28-2004 at 07:18 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  2. please help with binary tree, urgent.
    By slickestting in forum C Programming
    Replies: 2
    Last Post: 07-22-2007, 07:55 PM
  3. brace-enclosed error
    By jdc18 in forum C++ Programming
    Replies: 53
    Last Post: 05-03-2007, 05:49 PM
  4. Wrong Output
    By egomaster69 in forum C Programming
    Replies: 7
    Last Post: 01-28-2005, 06:44 PM
  5. Using 'if' with char arrays or string objects
    By c++_n00b in forum C++ Programming
    Replies: 36
    Last Post: 06-06-2002, 09:04 PM