Input-line reverser

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Albert

    #1

    Input-line reverser

    This not-yet-working C program's aim is to output each input line
    reversed (so if the user enters 'hello', the program will output
    'olleh' - and please assume this stdout and stdin!!!).
    Why the h**l isn't this WORKING AND WHY DOES IT CRASH???!

    #include <stdio.h>
    #define MAXINPUT 256

    void reverse(char[], int);

    main()
    {
    int c;
    int number;
    char s[MAXINPUT];
    int i;

    for (i=0; (i<MAXINPUT-1) && ((c = getchar()) != '\n'); i++) {
    s[i] = c;
    ++number;
    }
    reverse(s, number);


    for (i=0; i<=number; i++)
    putchar(s[i]);
    return 0;
    }


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

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

  • Richard Heathfield

    #2
    Re: Input-line reverser

    Albert said:
    [color=blue]
    > void reverse(char s[], int num_elements)
    > {
    > int i, j;
    >
    > for (i=0,j=num_elem ents-1; (i<=num_element s-1) && (j>=0); i++,j--)
    > s[i] = s[j];
    > }[/color]

    Desk-check it. That means: get out a piece of paper, and pretend you're a
    computer. Write down the values of all objects, each at the head of its own
    column. Assuming you have five elements:

    Code s[0] s[1] s[2] s[3] s[4] n i j
    'h' 'e' 'l' 'l' 'o' 5 ? ?

    Put down each code step in the left hand column, and look at the effect the
    code has on the values of all the relevant objects. For example:

    Code s[0] s[1] s[2] s[3] s[4] n i j
    'h' 'e' 'l' 'l' 'o' 5 ? ?
    i = 0 'h' 'e' 'l' 'l' 'o' 5 0 ?
    j = n-1 'h' 'e' 'l' 'l' 'o' 5 0 4
    i <= 4? Yes.
    j >= 0? Yes.
    s[i]=s[j] 'o' 'e' 'l' 'l' 'o' 5 0 4

    and so on. Doing this by hand - "desk-checking" - is an invaluable aid to
    understanding what you actually wrote, as opposed to what you thought you
    wrote.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999

    email: rjh at above domain (but drop the www, obviously)

    Comment

    • Arthur J. O'Dwyer

      #3
      Re: Input-line reverser


      On Thu, 29 Dec 2005, Albert wrote:[color=blue]
      >
      > Why the h**l isn't this WORKING AND WHY DOES IT CRASH???!
      >
      > #include <stdio.h>
      > #define MAXINPUT 256
      >
      > void reverse(char[], int);
      >
      > main()[/color]

      int main(void)
      [color=blue]
      > {
      > int c;
      > int number;
      > char s[MAXINPUT];
      > int i;
      >
      > for (i=0; (i<MAXINPUT-1) && ((c = getchar()) != '\n'); i++) {[/color]

      For bonus points, consider what happens if c is EOF.
      [color=blue]
      > s[i] = c;
      > ++number;[/color]

      What is 'number' at this point in the program? Hint: It depends
      on what 'number' was at the beginning of the program. Find where you
      (failed to) initialized 'number', and you'll have found the main
      problem. ...Okay, one of the /two/ main problems.
      [color=blue]
      > }
      > reverse(s, number);
      >
      >
      > for (i=0; i<=number; i++)
      > putchar(s[i]);[/color]

      What is 's[number]'? (For that matter, if you give 'number' a real
      name, such as 'length', you'll probably find out why you don't need
      it after all.)
      [color=blue]
      > return 0;
      > }
      >
      >
      > void reverse(char s[], int num_elements)
      > {
      > int i, j;
      >
      > for (i=0,j=num_elem ents-1; (i<=num_element s-1) && (j>=0); i++,j--)[/color]

      Once the program no longer crashes, it will be time to examine this
      loop's termination condition to find out why it doesn't do anything.
      [color=blue]
      > s[i] = s[j];
      > }[/color]


      -Arthur

      Comment

      • Albert

        #4
        Re: Input-line reverser

        Could you FIRSTLY tell me why this program crashes?

        Comment

        • Richard Heathfield

          #5
          Re: Input-line reverser

          Albert said:
          [color=blue]
          > Could you FIRSTLY tell me why this program crashes?[/color]

          Sure. It's because the program is not a valid C program. Now, you might
          argue that it compiles just fine, and runs just fine except for the
          crashing part, and is therefore a valid C program. But you'd be wrong.

          The reason it's not a valid C program is that it attempts to modify the
          value of an object, when that object hasn't been given a value yet.
          Specifically, look at 'number', in main, which you define but to which you
          assign no value. Therefore, that object's value is indeterminate.
          Nevertheless, you try to use that value (by adding 1 to it), thus invoking
          undefined behaviour, just as you would do if you were stupid enough (which,
          of course, you never will be) to define main with some return type other
          than int. In each case, the C language washes its hands of the program, and
          so the results are arbitrary. Crashing is just one of many possibilities.

          --
          Richard Heathfield
          "Usenet is a strange place" - dmr 29/7/1999

          email: rjh at above domain (but drop the www, obviously)

          Comment

          • Albert

            #6
            Re: Input-line reverser

            I've 'desk-checked' and I still can't figure out why if I enter 'he' it
            outputs 'ee'.
            Could you give me another hint?

            I've updated the program:

            #include <stdio.h>
            #define MAXINPUT 256


            void reverse(char[], int);


            main()
            {
            int c;
            int number = 0;
            char s[MAXINPUT];
            int i;


            for (i=0; (i<MAXINPUT-1) && ((c = getchar()) != '\n') && (c!=EOF);
            i++) {
            s[i] = c;
            ++number;
            }
            reverse(s, number);


            for (i=0; i<=number-1; i++)
            putchar(s[i]);
            return 0;
            }


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

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

            Comment

            • Arthur J. O'Dwyer

              #7
              Re: Input-line reverser


              On Thu, 29 Dec 2005, Albert wrote:[color=blue]
              >
              > Could you FIRSTLY tell me why this program crashes?[/color]

              Yes. You didn't provide any 'main' function.
              (Or are you talking about some other program? Why don't you provide
              the program in question, or at least some context for your remark?)

              If you're using Google Groups to post, *don't*. If you must, then
              go Google "Google Groups Usenet" and follow the instructions you find
              in re: netiquette.


              Note that Richard's reply was better than mine, because /he/ wasn't
              not paying enough attention to the 'reverse' function. ;) The second
              half of my reply was just plain wrong.

              -Arthur

              Comment

              • Richard Heathfield

                #8
                Re: Input-line reverser

                Albert said:
                [color=blue]
                > I've 'desk-checked' and I still can't figure out why if I enter 'he' it
                > outputs 'ee'.[/color]

                It's because you tell it to.
                [color=blue]
                > Could you give me another hint?[/color]

                Here are three hints:

                You are right to start at both ends and work inward.

                You should stop halfway. When i > j, you're done.

                You should use a temporary object to store one of the values when swapping.

                If you do s[i] = s[j], you lose the original value of s[i]. The idiom you
                need is:

                tmp = s[i];
                s[i] = s[j];
                s[j] = tmp;

                --
                Richard Heathfield
                "Usenet is a strange place" - dmr 29/7/1999

                email: rjh at above domain (but drop the www, obviously)

                Comment

                • Chris F.A. Johnson

                  #9
                  Re: Input-line reverser

                  On 2005-12-30, Albert wrote:[color=blue]
                  > I've 'desk-checked' and I still can't figure out why if I enter 'he' it
                  > outputs 'ee'.
                  > Could you give me another hint?[/color]
                  [snip][color=blue]
                  > void reverse(char s[], int num_elements)
                  > {
                  > int i, j;
                  >
                  > for (i=0,j=num_elem ents-1; (i<=num_element s-1) && (j>=0); i++,j--)
                  > s[i] = s[j];
                  > }[/color]

                  What are the values of s[0] and s[1] after the first iteration of
                  the loop?


                  --
                  Chris F.A. Johnson, author | <http://cfaj.freeshell. org>
                  Shell Scripting Recipes: | My code in this post, if any,
                  A Problem-Solution Approach | is released under the
                  2005, Apress | GNU General Public Licence

                  Comment

                  • Mark McIntyre

                    #10
                    Re: Input-line reverser

                    On 29 Dec 2005 20:35:17 -0800, in comp.lang.c , "Albert"
                    <albert.xtheunk nown0@gmail.com > wrote:
                    [color=blue]
                    >Could you FIRSTLY tell me why this program crashes?[/color]

                    When you desk-check it, you will discover the answer to that.

                    Really, Richard is trying to help you by explaining an important
                    technique in writing computer programmes. Its not all about typing on
                    keyboards.
                    Mark McIntyre
                    --

                    ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
                    http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
                    ----= East and West-Coast Server Farms - Total Privacy via Encryption =----

                    Comment

                    • Mark McIntyre

                      #11
                      Re: Input-line reverser

                      On 29 Dec 2005 20:49:17 -0800, in comp.lang.c , "Albert"
                      <albert.xtheunk nown0@gmail.com > wrote:
                      [color=blue]
                      >I've 'desk-checked' and I still can't figure out why if I enter 'he' it
                      >outputs 'ee'.[/color]

                      You have s[] = "he";

                      You set s[0] = s[1]
                      then you set s[1] = s[0]

                      what is now in the array?
                      [color=blue]
                      >Could you give me another hint?[/color]

                      You're swapping too much, and you need a temporary.
                      Mark McIntyre
                      --

                      ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
                      http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
                      ----= East and West-Coast Server Farms - Total Privacy via Encryption =----

                      Comment

                      • Mike Wahler

                        #12
                        Re: Input-line reverser


                        "Richard Heathfield" <invalid@invali d.invalid> wrote in message
                        news:dp2dp4$8qv $1@nwrdmz01.dmz .ncs.ea.ibs-infra.bt.com...[color=blue]
                        > Albert said:
                        >[color=green]
                        >> Could you FIRSTLY tell me why this program crashes?[/color]
                        >
                        > Sure. It's because the program is not a valid C program. Now, you might
                        > argue that it compiles just fine, and runs just fine except for the
                        > crashing part, and is therefore a valid C program. But you'd be wrong.
                        >
                        > The reason it's not a valid C program is that it attempts to modify[/color]

                        evaluate, not modify. Modifying (i.e. assigning to it) would be OK.
                        [color=blue]
                        > the
                        > value of an object, when that object hasn't been given a value yet.[/color]


                        -Mike


                        Comment

                        • August Karlstrom

                          #13
                          Re: Input-line reverser

                          Albert wrote:[color=blue]
                          > This not-yet-working C program's aim is to output each input line
                          > reversed (so if the user enters 'hello', the program will output
                          > 'olleh' - and please assume this stdout and stdin!!!).
                          > Why the h**l isn't this WORKING AND WHY DOES IT CRASH???!
                          >
                          > #include <stdio.h>
                          > #define MAXINPUT 256
                          >
                          > void reverse(char[], int);
                          >
                          > main()
                          > {
                          > int c;
                          > int number;
                          > char s[MAXINPUT];
                          > int i;
                          >
                          > for (i=0; (i<MAXINPUT-1) && ((c = getchar()) != '\n'); i++) {
                          > s[i] = c;
                          > ++number;
                          > }
                          > reverse(s, number);
                          >
                          >
                          > for (i=0; i<=number; i++)
                          > putchar(s[i]);
                          > return 0;
                          > }
                          >
                          >
                          > void reverse(char s[], int num_elements)
                          > {
                          > int i, j;
                          >
                          > for (i=0,j=num_elem ents-1; (i<=num_element s-1) && (j>=0); i++,j--)
                          > s[i] = s[j];
                          > }
                          >[/color]

                          You may also want to consider a much shorter solution using recursion.
                          It imposes no restrictions on the line length.

                          #include <stdio.h>

                          void reverse(void)
                          {
                          int c;

                          c = getchar();
                          if (c != '\n') {
                          reverse();
                          putchar(c);
                          }
                          }


                          int main(void)
                          {
                          reverse();
                          putchar('\n');
                          return 0;
                          }


                          August

                          --
                          I am the "ILOVEGNU" signature virus. Just copy me to your
                          signature. This email was infected under the terms of the GNU
                          General Public License.

                          Comment

                          • Richard Heathfield

                            #14
                            Re: Input-line reverser

                            Mike Wahler said:
                            [color=blue]
                            >
                            > "Richard Heathfield" <invalid@invali d.invalid> wrote in message
                            > news:dp2dp4$8qv $1@nwrdmz01.dmz .ncs.ea.ibs-infra.bt.com...[color=green]
                            >>
                            >> The reason it's not a valid C program is that it attempts to modify[/color]
                            >
                            > evaluate, not modify. Modifying (i.e. assigning to it) would be OK.[/color]

                            I plead the rest of my original sentence as justification.
                            [color=blue][color=green]
                            >> the
                            >> value of an object, when that object hasn't been given a value yet.[/color][/color]

                            --
                            Richard Heathfield
                            "Usenet is a strange place" - dmr 29/7/1999

                            email: rjh at above domain (but drop the www, obviously)

                            Comment

                            • Mark McIntyre

                              #15
                              Re: Input-line reverser

                              On Fri, 30 Dec 2005 15:26:25 GMT, in comp.lang.c , "Mike Wahler"
                              <mkwahler@mkwah ler.net> wrote:
                              [color=blue]
                              >
                              >"Richard Heathfield" <invalid@invali d.invalid> wrote in message
                              >[color=green]
                              >> The reason it's not a valid C program is that it attempts to modify[/color]
                              >
                              >evaluate, not modify. Modifying (i.e. assigning to it) would be OK[/color]

                              Not all modification is assignment. Consider if the modification were
                              for example ++ or +=.
                              Mark McIntyre
                              --

                              ----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
                              http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
                              ----= East and West-Coast Server Farms - Total Privacy via Encryption =----

                              Comment

                              Working...