String reversing problem

Discussion in 'C Programming' started by Albert, Dec 30, 2005.

  1. Albert

    Albert Guest

    Why doesn't:

    #include <stdio.h>

    void reverse(char[], int);

    main()
    {
    char s[5];

    s[0] = 'h';
    s[1] = 'e';
    s[2] = 'l';
    s[3] = 'l';
    s[4] = 'o';
    reverse(s, 5);

    for (int i=0; i<=4; i++)
    putchar(s);
    return 0;
    }

    void reverse(char s[], int num_elements)
    {
    int i, j;

    for (i=0,j=num_elements-1; (i<=num_elements-1) && (j>=0); i++,j--)
    s = s[j];
    }

    output:

    olleh

    ?
    Albert, Dec 30, 2005
    #1
    1. Advertising

  2. Albert

    Artie Gold Guest

    Albert wrote:
    > Why doesn't:
    >
    > #include <stdio.h>
    >
    > void reverse(char[], int);
    >
    > main()
    > {
    > char s[5];
    >
    > s[0] = 'h';
    > s[1] = 'e';
    > s[2] = 'l';
    > s[3] = 'l';
    > s[4] = 'o';
    > reverse(s, 5);
    >
    > for (int i=0; i<=4; i++)
    > putchar(s);
    > return 0;
    > }
    >
    > void reverse(char s[], int num_elements)
    > {
    > int i, j;
    >
    > for (i=0,j=num_elements-1; (i<=num_elements-1) && (j>=0); i++,j--)


    Think what happens when i==4 and j==1, for example. [Do they still call
    it `desk checking'?]

    > s = s[j];
    > }
    >
    > output:
    >
    > olleh
    >
    > ?
    >

    HTH,
    --ag

    --
    Artie Gold -- Austin, Texas
    http://goldsays.blogspot.com (new post 8/5)
    http://www.cafepress.com/goldsays
    "If you have nothing to hide, you're not trying!"
    Artie Gold, Dec 30, 2005
    #2
    1. Advertising

  3. Albert

    Diptendra Guest

    use this one
    #include <stdio.h>


    void reverse(char[], int);


    main()
    {
    char s[5];
    int i;

    s[0] = 'h';
    s[1] = 'e';
    s[2] = 'l';
    s[3] = 'l';
    s[4] = 'o';
    reverse(s, 5);


    for ( i = 0; i<=4; i++)
    putchar(s);
    return 0;



    }


    void reverse(char s[], int num_elements)
    {
    int i, j;

    for (i=0,j=num_elements-1; (i<=num_elements-1) && (j>=0); i++,j--)
    s = s[j];



    }
    Diptendra, Dec 30, 2005
    #3
  4. Albert

    Albert Guest

    What do you mean by 'desk checking'?
    Albert, Dec 30, 2005
    #4
  5. Albert

    Guest

    Albert wrote:
    > What do you mean by 'desk checking'?


    I think he means checking by pen & paper. I'd call it "checking by pen
    & paper" although I always use a whiteboard for it.

    Computers can only do what you tell them to do. As they say: garbage
    in, garbage out. Sometimes when the computer doesn't do what you want
    it is worth checking if you told it to do what you thought you wanted.
    , Dec 30, 2005
    #5
  6. Albert

    Guest

    Albert wrote:
    > Why doesn't:
    >
    > <snip>
    > s = s[j];
    >


    This is a good example of why desk-checking is good. Lets take a
    "hello" string shall we? Note that in the "diagram" below I mark the
    variable being "read" from with + and the variable being "written" to
    with ^.

    h e l l o // original string

    o e l l o // doing s[0] = s[4]
    ^ +

    o l l l o // doing s[1] = s[3]
    ^ +

    o l l l o // doing s[2] = s[2]
    ^

    o l l l o // doing s[3] = s[1]
    + ^

    At this point I hope you see the problem with you code since you've
    overwritten the original 'e' with an 'l'.
    , Dec 30, 2005
    #6
  7. Albert

    pai Guest

    hi ,
    I think an extra variable is needed to store, bcoz u cant
    interchange 2 variable as such.
    or is there any way to do it ...
    Pai
    pai, Dec 30, 2005
    #7
  8. pai said:

    > hi ,
    > I think an extra variable is needed to store, bcoz u cant
    > interchange 2 variable as such.
    > or is there any way to do it ...


    There is a way to do this under certain conditions, but it's not a very
    bright idea.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
    Richard Heathfield, Dec 30, 2005
    #8
  9. Albert

    Chuck F. Guest

    pai wrote:
    >
    > I think an extra variable is needed to store, bcoz u cant
    > interchange 2 variable as such. or is there any way to do it
    >

    Include context, without which your message is meaningless. For
    means on the broken google interface, see my sig below.

    Try this, after #include <string.h>:

    /* reverse string in place. Return length */
    static size_t revstring(char *stg)
    {
    char *last, temp;
    size_t lgh;

    if ((lgh = strlen(stg)) > 1) {
    last = stg + lgh; /* points to '\0' */
    while (last-- > stg) {
    temp = *stg; *stg++ = *last; *last = temp;
    }
    }
    return lgh;
    } /* revstring */

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
    Chuck F., Dec 30, 2005
    #9
  10. Albert

    haroon Guest

    Albert wrote:
    > Why doesn't:

    [...]
    > void reverse(char s[], int num_elements)
    > {
    > int i, j;
    >
    > for (i=0,j=num_elements-1; (i<=num_elements-1) && (j>=0); i++,j--)
    > s = s[j];
    > }


    try writing reverse(...) like this:

    /***/
    void reverse(char s[], int num_elements)
    {
    int i, j;
    char t;

    for (i=0,j=num_elements-1; (i<=(num_elements-1) / 2) && (j>=0);
    i++,j--)
    {
    t = s;
    s = s[j];
    s[j] = t;
    }
    }

    /***/

    then analyze both to figure out whats the difference and what happend.
    haroon, Dec 30, 2005
    #10
  11. Albert

    tmp123 Guest

    Chuck F. wrote:
    > pai wrote:
    > >
    > > I think an extra variable is needed to store, bcoz u cant
    > > interchange 2 variable as such. or is there any way to do it
    > >

    > Include context, without which your message is meaningless. For
    > means on the broken google interface, see my sig below.
    >
    > Try this, after #include <string.h>:
    >
    > /* reverse string in place. Return length */
    > static size_t revstring(char *stg)
    > {
    > char *last, temp;
    > size_t lgh;
    >
    > if ((lgh = strlen(stg)) > 1) {
    > last = stg + lgh; /* points to '\0' */
    > while (last-- > stg) {
    > temp = *stg; *stg++ = *last; *last = temp;
    > }
    > }
    > return lgh;
    > } /* revstring */
    >
    > --
    > "If you want to post a followup via groups.google.com, don't use
    > the broken "Reply" link at the bottom of the article. Click on
    > "show options" at the top of the article, then click on the
    > "Reply" at the bottom of the article headers." - Keith Thompson
    > More details at: <http://cfaj.freeshell.org/google/>


    Hi,

    I agree on the previous, and, of course, if some day I need to code
    something similar I will write more or less the same (specially in an
    answer to a beginner).

    But, just for fun, and taken into account is the third time this
    question has been posted, another version:

    int revstring ( char *s )
    {
    char *e;
    int r;
    for( e=s+(r=strlen(s))-1; s<e; *s^=*e^=*s^=*e, s++, e--);
    return r;
    }


    Kind regards.

    (hope google doesn't heats indentation).
    tmp123, Dec 30, 2005
    #11
  12. "Albert" <> wrote in message
    news:...
    > What do you mean by 'desk checking'?


    I'd have called it "paper check," or, when I'm feeling whimsical "let's play
    computer."

    Whatever way it's expressed, it means get out some paper and a pen(cil) and
    perform, yourself, the steps the computer will take to execute your program.
    Sometimes it's better (or quicker) than a debugger. Sometimes it's the only
    way to debug (for very limited platforms, for example). Well worth practicing.

    - Bill
    William J. Leary Jr., Dec 30, 2005
    #12
  13. Albert

    Chuck F. Guest

    tmp123 wrote:
    > Chuck F. wrote:
    >

    .... snip ...
    >
    >> /* reverse string in place. Return length */
    >> static size_t revstring(char *stg)
    >> {
    >> char *last, temp;
    >> size_t lgh;
    >>
    >> if ((lgh = strlen(stg)) > 1) {
    >> last = stg + lgh; /* points to '\0' */
    >> while (last-- > stg) {
    >> temp = *stg; *stg++ = *last; *last = temp;
    >> }
    >> }
    >> return lgh;
    >> } /* revstring */

    >

    .... snip ...
    >
    > But, just for fun, and taken into account is the third time this
    > question has been posted, another version:
    >
    > int revstring ( char *s )
    > {
    > char *e;
    > int r;
    > for( e=s+(r=strlen(s))-1; s<e; *s^=*e^=*s^=*e, s++, e--);
    > return r;
    > }


    FYI your version invokes undefined behaviour. Try it with a string
    of zero chars. My length test is not there for fun. I also have
    evil suspicions about the xor operations.

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
    Chuck F., Dec 30, 2005
    #13
  14. Albert

    tmp123 Guest

    Chuck F. wrote:
    > tmp123 wrote:
    > > int revstring ( char *s )
    > > {
    > > char *e;
    > > int r;
    > > for( e=s+(r=strlen(s))-1; s<e; *s^=*e^=*s^=*e, s++, e--);
    > > return r;
    > > }

    >
    > FYI your version invokes undefined behaviour. Try it with a string
    > of zero chars. My length test is not there for fun. I also have
    > evil suspicions about the xor operations.
    >


    Hi,

    If length is 0, then e=s-1, thus s<e is false exiting loop.

    However, if the usage of pointer comparation and pointer substraction
    is not welcome, another version:

    void revstring ( char *s )
    {
    char *e;
    for( e=s+strlen(s); s!=e-- && s!=e; *s^=*e^=*s++^=*e);
    }

    Kind regards.

    PS: some days ago, someone posted about if "C is easy". I do not known,
    but it is tricky.
    tmp123, Dec 30, 2005
    #14
  15. "tmp123" <> writes:
    [...]
    > void revstring ( char *s )
    > {
    > char *e;
    > for( e=s+strlen(s); s!=e-- && s!=e; *s^=*e^=*s++^=*e);
    > }


    Undefined behavior.

    > PS: some days ago, someone posted about if "C is easy". I do not known,
    > but it is tricky.


    It can be if you go out of your way to make it tricky.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Dec 30, 2005
    #15
  16. Albert

    tmp123 Guest

    Keith Thompson wrote:
    > "tmp123" <> writes:
    > [...]
    > > void revstring ( char *s )
    > > {
    > > char *e;
    > > for( e=s+strlen(s); s!=e-- && s!=e; *s^=*e^=*s++^=*e);
    > > }

    >
    > Undefined behavior.
    >


    Could be... but, could you prove your statement?
    tmp123, Dec 30, 2005
    #16
  17. Albert

    Tim Rentsch Guest

    "tmp123" <> writes:

    > Keith Thompson wrote:
    > > "tmp123" <> writes:
    > > [...]
    > > > void revstring ( char *s )
    > > > {
    > > > char *e;
    > > > for( e=s+strlen(s); s!=e-- && s!=e; *s^=*e^=*s++^=*e);
    > > > }

    > >
    > > Undefined behavior.
    > >

    >
    > Could be... but, could you prove your statement?


    Even the first half of the control expression (namely, 's!=e--')
    can yield undefined behavior if strlen(s) == 0.
    Tim Rentsch, Dec 30, 2005
    #17
  18. "tmp123" <> writes:
    > Keith Thompson wrote:
    >> "tmp123" <> writes:
    >> [...]
    >> > void revstring ( char *s )
    >> > {
    >> > char *e;
    >> > for( e=s+strlen(s); s!=e-- && s!=e; *s^=*e^=*s++^=*e);
    >> > }

    >>
    >> Undefined behavior.
    >>

    >
    > Could be... but, could you prove your statement?


    The expression
    *s^=*e^=*s++^=*e
    modifies both *s and *e twice between sequence points.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
    We must do something. This is something. Therefore, we must do this.
    Keith Thompson, Dec 30, 2005
    #18
  19. In article <>,
    "tmp123" <> wrote:

    > Keith Thompson wrote:
    > > "tmp123" <> writes:
    > > [...]
    > > > void revstring ( char *s )
    > > > {
    > > > char *e;
    > > > for( e=s+strlen(s); s!=e-- && s!=e; *s^=*e^=*s++^=*e);
    > > > }

    > >
    > > Undefined behavior.
    > >

    >
    > Could be... but, could you prove your statement?


    It's kind of obvious. Even if it wasn't, whoever wrote that kind of code
    should be slapped silly. Immediate removal from any programming team
    that I am involved with.
    Christian Bau, Dec 30, 2005
    #19
  20. Albert

    Chuck F. Guest

    tmp123 wrote:
    > Chuck F. wrote:
    >> tmp123 wrote:
    >> > int revstring ( char *s )
    >> > {
    >> > char *e;
    >> > int r;
    >> > for( e=s+(r=strlen(s))-1; s<e; *s^=*e^=*s^=*e, s++, e--);
    >> > return r;
    >> > }

    >>
    >> FYI your version invokes undefined behaviour. Try it with a
    >> string of zero chars. My length test is not there for fun. I
    >> also have evil suspicions about the xor operations.

    >
    > If length is 0, then e=s-1, thus s<e is false exiting loop.
    >
    > However, if the usage of pointer comparation and pointer
    > substraction is not welcome, another version:


    > void revstring ( char *s )
    > {
    > char *e;
    > for( e=s+strlen(s); s!=e-- && s!=e; *s^=*e^=*s++^=*e);
    > }


    Same problem and undefined behaviour. You are not allowed to
    generate a pointer that points before s (although you are allowed
    to generate one that points just after s).

    --
    "If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers." - Keith Thompson
    More details at: <http://cfaj.freeshell.org/google/>
    Chuck F., Dec 30, 2005
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. netforce

    reversing a string - newbie question

    netforce, Mar 2, 2004, in forum: C Programming
    Replies:
    9
    Views:
    529
    Old Wolf
    Mar 8, 2004
  2. Lindsay
    Replies:
    3
    Views:
    280
    upashu2
    Jul 18, 2005
  3. Kelly B

    Reversing order of words in a given string

    Kelly B, Apr 26, 2007, in forum: C Programming
    Replies:
    2
    Views:
    351
    Kelly B
    Apr 26, 2007
  4. Scott

    Reversing a string

    Scott, Jun 27, 2007, in forum: Python
    Replies:
    23
    Views:
    590
    Martin Durkin
    Jul 5, 2007
  5. Rubist Rohit
    Replies:
    19
    Views:
    608
    Adam Prescott
    Apr 23, 2011
Loading...

Share This Page