stream io in c

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

    #31
    Re: stream io in c

    On 31 Jul, 15:06, CBFalconer <cbfalco...@yah oo.comwrote:
    Nick Keighleywrote:
    Ron Ford <r...@example.i nvalidwrote:
    >
    ... snip ...
    >
    I've tried some variations with this.
    >
    int i;
    for (i = 0; i <= UCHAR_MAX; i++) putchar (i);
    >
     for (i = 0; i <  UCHAR_MAX; i++) putchar (i);
    >
    No, the original is correct.  He wants to write out the entire
    range available to the char type.
    yes. I was mistaken.

    --
    Nick Keighley

    Comment

    • Keith Thompson

      #32
      Re: stream io in c

      Ron Ford <ron@example.in validwrites:
      On Thu, 31 Jul 2008 16:04:13 +0530, santosh posted:
      >
      >Can you spot the mistake in this printf call?
      >>
      >
      I think I got it:
      Better.
      //mkchars.c:
      >
      >
      >
      #include <stdio.h>
      #include <stdlib.h>
      #include <limits.h>
      >
      int main(void)
      {
      FILE *fp;
      char name[]="chars.256" ;
      >
      >
      unsigned char c;
      >
      >
      >
      if ((fp = fopen(name, "wb")) == NULL)
      {
      printf("can't open %s\n", name);
      I'd change this to:

      fprintf(stderr, "can't open %s\n", name);
      return EXIT_FAILURE;
      }
      else
      {
      for (c = 0; c <= UCHAR_MAX; c ++) {
      As others have pointed out, this loop never terminates. c is of type
      unsigned char; it's *always" <= UCHAR_MAX, no matter what you do with
      it.
      putc(c, fp);
      }
      fclose(fp);
      }
      return 0;
      }
      // gcc -o chars -std=c99 -pedantic -Wall -W mkchars4.c
      >
      I created a problem for myself that I don't get. I checked that UCHAR_MAX
      was indeed 255 on my machine, but the subtitution for 255 causes this
      warning and the program to hang:
      >
      >
      C:\MinGW\source >gcc -o chars -std=c99 -pedantic -Wall -W mkchars3.c
      mkchars3.c: In function 'main':
      mkchars3.c:26: warning: comparison is always true due to limited range of
      data type
      >
      I think I get it. 255 ++ = 0 ?
      Um, no. 255++ is an error (specifically a constraint violation).

      Remember, the "++" operator (prefix or postfix) does two things: it
      modifies its argument, and it yields a value (either the previous
      value or the modified value depending on where you put the "++").
      You can't modify 255, so 255++ doesn't make any sense.

      New C programmers are often fascinated by C's ++ operator. It's such
      a cool and terse way to specify that you want to increment something.
      But "x++" doesn't mean "x+1"; it's more complex than that. If you
      want the incremented value of x without modifying x as a side effect,
      just write "x+1". (And if you replace x with a constant 255,
      you *can't* modify it.)

      So what you're really asking is whether 255 + 1 == 0.

      As stated, no, but there's a true statement hiding in there.

      *If* UCHAR_MAX is 255 (as it very commonly is), and if you have an
      object of type unsigned char with the value 255, then incrementing
      that object will cause it to have the value 0.

      For all unsigned types, arithmetic is performed in a wraparound
      manner. So UINT_MAX + 1U == 0U, and ULONG_MAX + 1UL == 0UL.
      Conversely, 0U - 1U == UINT_MAX.

      And in many cases you still have to worry about promoitions and other
      implicit conversions. For example, consider this:

      #include <stdio.h>
      #include <limits.h>
      int main(void)
      {
      unsigned char c = UCHAR_MAX;
      unsigned char c1 = c + 1;
      int i1 = c + 1;

      printf("c1 = %d\n", (int)c1);
      printf("i1 = %d\n", i1);
      return 0;
      }

      c1 gets the value 0; i1 gets the value 256. That's because, in the
      expression c + 1, the value of c is implicitly promoted to int; adding
      1 to an int value of 255 doesn't overflow or wrap around, it just
      yields 256.

      And although the initialization of c1 to c + 1 *acts* like it's adding
      1 to an unsigned char value of 255, wrapping around, and yielding 0,
      what really happens is that the value of c is promoted to int, the
      expression c + 1 yields the int value 256, and that value is then
      *converted* to unsigned char, yielding 0. The final result is the
      same, but we took a detour from unsigned char to int and back to
      unsigned char.

      For integers, these implicit promotions only occur (and only in some
      circumstances) for types narrower than int and unsigned int.

      --
      Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
      Nokia
      "We must do something. This is something. Therefore, we must do this."
      -- Antony Jay and Jonathan Lynn, "Yes Minister"

      Comment

      • Ron Ford

        #33
        Re: stream io in c

        On Fri, 01 Aug 2008 10:17:36 -0700, Keith Thompson posted:
        Ron Ford <ron@example.in validwrites:
        [snipped and re-ordered]
        Um, no. 255++ is an error (specifically a constraint violation).
        >
        Remember, the "++" operator (prefix or postfix) does two things: it
        modifies its argument, and it yields a value (either the previous
        value or the modified value depending on where you put the "++").
        You can't modify 255, so 255++ doesn't make any sense.
        >
        New C programmers are often fascinated by C's ++ operator. It's such
        a cool and terse way to specify that you want to increment something.
        But "x++" doesn't mean "x+1"; it's more complex than that. If you
        want the incremented value of x without modifying x as a side effect,
        just write "x+1". (And if you replace x with a constant 255,
        you *can't* modify it.)
        >
        So what you're really asking is whether 255 + 1 == 0.
        >
        As stated, no, but there's a true statement hiding in there.
        >
        *If* UCHAR_MAX is 255 (as it very commonly is), and if you have an
        object of type unsigned char with the value 255, then incrementing
        that object will cause it to have the value 0.
        >
        For all unsigned types, arithmetic is performed in a wraparound
        manner. So UINT_MAX + 1U == 0U, and ULONG_MAX + 1UL == 0UL.
        Conversely, 0U - 1U == UINT_MAX.
        >
        And in many cases you still have to worry about promoitions and other
        implicit conversions. For example, consider this:
        >
        #include <stdio.h>
        #include <limits.h>
        int main(void)
        {
        unsigned char c = UCHAR_MAX;
        unsigned char c1 = c + 1;
        int i1 = c + 1;
        >
        printf("c1 = %d\n", (int)c1);
        printf("i1 = %d\n", i1);
        return 0;
        }
        >
        c1 gets the value 0; i1 gets the value 256. That's because, in the
        expression c + 1, the value of c is implicitly promoted to int; adding
        1 to an int value of 255 doesn't overflow or wrap around, it just
        yields 256.
        >
        And although the initialization of c1 to c + 1 *acts* like it's adding
        1 to an unsigned char value of 255, wrapping around, and yielding 0,
        what really happens is that the value of c is promoted to int, the
        expression c + 1 yields the int value 256, and that value is then
        *converted* to unsigned char, yielding 0. The final result is the
        same, but we took a detour from unsigned char to int and back to
        unsigned char.
        >
        For integers, these implicit promotions only occur (and only in some
        circumstances) for types narrower than int and unsigned int.
        I'm gonna need a little time to go through this more carefully.
        I'd change this to:
        >
        fprintf(stderr, "can't open %s\n", name);
        >
        This change highlights the use of the second line of what I call the
        goocher: the commented-out command lines. I would definitely expect
        information like this to come from stderr.

        //mkchars.c:

        #include <stdio.h>
        #include <stdlib.h>
        #include <limits.h>

        int main(void)
        {
        FILE *fp;
        char name[]="chars.256" ;
        int c;

        if ((fp = fopen(name, "wb")) == NULL)
        {
        fprintf(stderr, "couldn't open %s\n", name);
        return EXIT_FAILURE;
        }
        else
        {
        printf("creatin g %s\n", name);
        for (c = 0; c <= UCHAR_MAX; c ++) {
        putc(c, fp);
        }
        fprintf(stderr, "did open %s\n", name);
        fclose(fp);
        }
        return 0;
        }
        // gcc -o chars -std=c99 -pedantic -Wall -W mkchars5.c
        // chars >text55.txt 2>text56.txt

        The first two commands were without the fprintf's:

        C:\MinGW\source gcc -o chars -std=c99 -pedantic -Wall -W mkchars5.c

        C:\MinGW\source >chars
        creating chars.256

        C:\MinGW\source >gcc -o chars -std=c99 -pedantic -Wall -W mkchars5.c

        C:\MinGW\source >chars
        creating chars.256
        did open chars.256

        C:\MinGW\source >chars >text55.txt 2>text56.txt

        C:\MinGW\source >


        So it is that text55 has the "creating" and text56 has the "did open" line.
        I like the reassurance from stderr that there was no error.

        --
        Unquestionably, there is progress. The average American now pays out twice
        as much in taxes as he formerly got in wages. 1
        H. L. Mencken

        Comment

        • santosh

          #34
          Re: stream io in c

          Ron Ford wrote:

          <snip>

          [code indentation corrected]
          //mkchars.c:
          >
          #include <stdio.h>
          #include <stdlib.h>
          #include <limits.h>
          >
          int main(void)
          {
          FILE *fp;
          char name[]="chars.256" ;
          int c;
          >
          if ((fp = fopen(name, "wb")) == NULL)
          {
          fprintf(stderr, "couldn't open %s\n", name);
          return EXIT_FAILURE;
          }
          else
          {
          printf("creatin g %s\n", name);
          for (c = 0; c <= UCHAR_MAX; c ++) {
          putc(c, fp);
          }
          fprintf(stderr, "did open %s\n", name);
          Typically only error messages are sent to stderr. A normal program
          message is usually sent to stdout.
          fclose(fp);
          }
          return 0;
          }
          BTW, I notice that you seem to have just as much problem with consistent
          formatting of your code that Bill C has.

          If you use an editor like Vim or Emacs it will automatically do most of
          the indenting for you. Inconsistent indentation and formatting makes
          your code difficult to read, when as it is, reading properly indented
          code is difficult enough.

          <snip>

          Comment

          • CBFalconer

            #35
            Re: stream io in c

            santosh wrote:
            Ron Ford wrote:
            >
            <snip>
            >
            >#include <stdio.h>
            >#include <stdlib.h>
            >#include <limits.h>
            >>
            >int main(void) { /* code tautened - cbf */
            > FILE *fp;
            > char name[]="chars.256" ;
            > int c;
            >>
            > if ((fp = fopen(name, "wb")) == NULL) {
            > fprintf(stderr, "couldn't open %s\n", name);
            > return EXIT_FAILURE;
            > }
            > else {
            > printf("creatin g %s\n", name);
            > for (c = 0; c <= UCHAR_MAX; c ++) {
            > putc(c, fp);
            > }
            > fprintf(stderr, "did open %s\n", name);
            >
            Typically only error messages are sent to stderr. A normal program
            message is usually sent to stdout.
            However here he is keeping track of file statuses on stderr, so I
            think the file choice is quite reasonable. It doesn't disturb the
            real action, and the actual output could be to stdout.

            --
            [mail]: Chuck F (cbfalconer at maineline dot net)
            [page]: <http://cbfalconer.home .att.net>
            Try the download section.


            Comment

            • pete

              #36
              Re: stream io in c

              Nick Keighley wrote:
              On 31 Jul, 15:06, CBFalconer <cbfalco...@yah oo.comwrote:
              >Nick Keighleywrote:
              >>Ron Ford <r...@example.i nvalidwrote:
              >... snip ...
              >>
              >>>I've tried some variations with this.
              >>>int i;
              >>>for (i = 0; i <= UCHAR_MAX; i++) putchar (i);
              >> for (i = 0; i < UCHAR_MAX; i++) putchar (i);
              >No, the original is correct. He wants to write out the entire
              >range available to the char type.
              >
              yes. I was mistaken.
              The original one is an endless loop,
              the second one doesn't putchar(UCHAR_M AX).

              unsigned i = 0;

              do {
              putchar (i);
              } while (i++ != UCHAR_MAX);


              --
              pete

              Comment

              • pete

                #37
                Re: stream io in c

                pete wrote:
                Nick Keighley wrote:
                >On 31 Jul, 15:06, CBFalconer <cbfalco...@yah oo.comwrote:
                >>Nick Keighleywrote:
                >>>Ron Ford <r...@example.i nvalidwrote:
                >>... snip ...
                >>>
                >>>>I've tried some variations with this.
                >>>>int i;
                >>>>for (i = 0; i <= UCHAR_MAX; i++) putchar (i);
                >>> for (i = 0; i < UCHAR_MAX; i++) putchar (i);
                >>No, the original is correct. He wants to write out the entire
                >>range available to the char type.
                >>
                >yes. I was mistaken.
                >
                The original one is an endless loop,
                It isn't an endless loop.
                I had read and recalled the original post
                which had declared (i) as unsigned char,
                and I made a mistake.
                the second one doesn't putchar(UCHAR_M AX).
                >
                unsigned i = 0;
                >
                do {
                putchar (i);
                } while (i++ != UCHAR_MAX);
                >
                >

                --
                pete

                Comment

                • santosh

                  #38
                  Re: stream io in c

                  pete wrote:
                  pete wrote:
                  >Nick Keighley wrote:
                  >>On 31 Jul, 15:06, CBFalconer <cbfalco...@yah oo.comwrote:
                  >>>Nick Keighleywrote:
                  >>>>Ron Ford <r...@example.i nvalidwrote:
                  >>>... snip ...
                  >>>>
                  >>>>>I've tried some variations with this.
                  >>>>>int i;
                  >>>>>for (i = 0; i <= UCHAR_MAX; i++) putchar (i);
                  >>>> for (i = 0; i < UCHAR_MAX; i++) putchar (i);
                  >>>No, the original is correct. He wants to write out the entire
                  >>>range available to the char type.
                  >>>
                  >>yes. I was mistaken.
                  >>
                  >The original one is an endless loop,
                  >
                  It isn't an endless loop.
                  It isn't an endless loop, but it does potentially invoke undefined
                  behaviour if UCHAR_MAX INT_MAX.

                  <snip>

                  Comment

                  • CBFalconer

                    #39
                    Re: stream io in c

                    santosh wrote:
                    pete wrote:
                    >pete wrote:
                    >>>CBFalconer <cbfalco...@yah oo.comwrote:
                    >>>>>Ron Ford <r...@example.i nvalidwrote:
                    >>>>... snip ...
                    >>>>>
                    >>>>>>I've tried some variations with this.
                    >>>>>>int i;
                    >>>>>>for (i = 0; i <= UCHAR_MAX; i++) putchar (i);
                    >>>>>>
                    >>>>No, the original is correct. He wants to write out the
                    >>>>entire range available to the char type.
                    >>>
                    >>The original one is an endless loop,
                    >>
                    >It isn't an endless loop.
                    >
                    It isn't an endless loop, but it does potentially invoke
                    undefined behaviour if UCHAR_MAX INT_MAX.
                    I don't believe that is allowable. == yes.

                    --
                    [mail]: Chuck F (cbfalconer at maineline dot net)
                    [page]: <http://cbfalconer.home .att.net>
                    Try the download section.


                    Comment

                    • vippstar@gmail.com

                      #40
                      Re: stream io in c

                      On Aug 4, 11:53 pm, CBFalconer <cbfalco...@yah oo.comwrote:
                      santosh wrote:
                      pete wrote:
                      pete wrote:
                      >>CBFalconer <cbfalco...@yah oo.comwrote:
                      >>>>Ron Ford <r...@example.i nvalidwrote:
                      >>>... snip ...
                      >
                      >>>>>I've tried some variations with this.
                      >>>>>int i;
                      >>>>>for (i = 0; i <= UCHAR_MAX; i++) putchar (i);
                      >
                      >>>No, the original is correct. He wants to write out the
                      >>>entire range available to the char type.
                      >
                      >The original one is an endless loop,
                      >
                      It isn't an endless loop.
                      >
                      It isn't an endless loop, but it does potentially invoke
                      undefined behaviour if UCHAR_MAX INT_MAX.
                      >
                      I don't believe that is allowable. == yes.
                      It is. It's not allowable that UCHAR_MAX UINT_MAX.

                      Comment

                      • Keith Thompson

                        #41
                        Re: stream io in c

                        CBFalconer <cbfalconer@yah oo.comwrites:
                        santosh wrote:
                        >pete wrote:
                        >>pete wrote:
                        >>>>CBFalcone r <cbfalco...@yah oo.comwrote:
                        >>>>>>Ron Ford <r...@example.i nvalidwrote:
                        >>>>>... snip ...
                        >>>>>>
                        >>>>>>>I've tried some variations with this.
                        >>>>>>>int i;
                        >>>>>>>for (i = 0; i <= UCHAR_MAX; i++) putchar (i);
                        >>>>>>>
                        >>>>>No, the original is correct. He wants to write out the
                        >>>>>entire range available to the char type.
                        >>>>
                        >>>The original one is an endless loop,
                        >>>
                        >>It isn't an endless loop.
                        >>
                        >It isn't an endless loop, but it does potentially invoke
                        >undefined behaviour if UCHAR_MAX INT_MAX.
                        >
                        I don't believe that is allowable. == yes.
                        I believe it is.

                        Consider CHAR_BIT==32, sizeof(int)==1, 2's-complement, no padding
                        bits. Then UCHAR_MAX==2**3 2-1, and INT_MAX==2**31-1.

                        It causes problems for stdio, but (a) it's not clear that's enough to
                        make the (hypothetical) implementation non-conforming, and (b) even if
                        it is, we can assume it's freestanding.

                        --
                        Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                        Nokia
                        "We must do something. This is something. Therefore, we must do this."
                        -- Antony Jay and Jonathan Lynn, "Yes Minister"

                        Comment

                        • Flash Gordon

                          #42
                          Re: stream io in c

                          Keith Thompson wrote, On 05/08/08 00:52:
                          CBFalconer <cbfalconer@yah oo.comwrites:
                          >santosh wrote:
                          >>pete wrote:
                          >>>pete wrote:
                          >>>>>CBFalcon er <cbfalco...@yah oo.comwrote:
                          >>>>>>>Ron Ford <r...@example.i nvalidwrote:
                          >>>>>>... snip ...
                          >>>>>>>
                          >>>>>>>>I've tried some variations with this.
                          >>>>>>>>int i;
                          >>>>>>>>for (i = 0; i <= UCHAR_MAX; i++) putchar (i);
                          >>>>>>No, the original is correct. He wants to write out the
                          >>>>>>entire range available to the char type.
                          >>>>The original one is an endless loop,
                          >>>It isn't an endless loop.
                          >>It isn't an endless loop, but it does potentially invoke
                          >>undefined behaviour if UCHAR_MAX INT_MAX.
                          >I don't believe that is allowable. == yes.
                          >
                          I believe it is.
                          >
                          Consider CHAR_BIT==32, sizeof(int)==1, 2's-complement, no padding
                          bits. Then UCHAR_MAX==2**3 2-1, and INT_MAX==2**31-1.
                          >
                          It causes problems for stdio, but (a) it's not clear that's enough to
                          make the (hypothetical) implementation non-conforming,
                          Note that there are a lot of *real* implementations where sizeof(int)==1
                          and CHAR_BIT is 16 or greater (including ones where it is 32).
                          and (b) even if
                          it is, we can assume it's freestanding.
                          All the implementations I know of are freestanding but I don't know all
                          implementations .
                          --
                          Flash Gordon

                          Comment

                          Working...