gets, fgets Question

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

    gets, fgets Question

    int get_lines(char *lines[])
    {
    int n = 0;
    char buffer[80];

    puts("Enter one line at time; enter a blank when done");

    while ((n < MAXLINES) && (gets(buffer) !=0 ) && (buffer[0] != '\0'))
    {
    if ((lines[n] = malloc(strlen(b uffer)+1)) == NULL)
    return -1;
    strcpy (lines[n++], buffer);
    }
    return n;
    }

    the above code is from the book ' Teach yourself C '
    it's for reading a row at a time, and if i just press enter without any
    input, the loop terminates.

    Question..

    1. gets(buffer) !=0 --> what does this mean ?
    as far as i know, 'gets' function returns NULL when error occurs,
    so it means gets(buffer) !=NULL ?
    either of them is alright ?

    2. I'd like to change the while statement using fgets.
    so i tried the below

    while ((n < MAXLINES) && (fgets(buffer,8 0,stdin) !=0 ) &&
    (buffer[0] != '\0'))
    BUT !!
    the loop doesn't end when i press enter without any input.
    i guess (buffer[0] != '\0')) is wrong..

    Thanks in advance..

    BTW ,, i saw a group, comp.lang.c.mod erated,, what's the difference ?

  • Robert Stankowic

    #2
    Re: gets, fgets Question


    "herrcho" <herrcho2803@ko rnet.net> schrieb im Newsbeitrag
    news:bkua3i$e1k $1@news1.kornet .net...[color=blue]
    > int get_lines(char *lines[])
    > {
    > int n = 0;
    > char buffer[80];
    >
    > puts("Enter one line at time; enter a blank when done");
    >
    > while ((n < MAXLINES) && (gets(buffer) !=0 ) && (buffer[0] != '\0'))
    > {
    > if ((lines[n] = malloc(strlen(b uffer)+1)) == NULL)
    > return -1;
    > strcpy (lines[n++], buffer);
    > }
    > return n;
    > }
    >
    > the above code is from the book ' Teach yourself C '[/color]

    Burn the book ;)
    [color=blue]
    > it's for reading a row at a time, and if i just press enter without any
    > input, the loop terminates.
    >
    > Question..
    >
    > 1. gets(buffer) !=0 --> what does this mean ?
    > as far as i know, 'gets' function returns NULL when error occurs,
    > so it means gets(buffer) !=NULL ?
    > either of them is alright ?[/color]

    Yes
    [color=blue]
    >
    > 2. I'd like to change the while statement using fgets.[/color]

    Bravo :)
    [color=blue]
    > so i tried the below
    >
    > while ((n < MAXLINES) && (fgets(buffer,8 0,stdin) !=0 ) &&
    > (buffer[0] != '\0'))
    > BUT !!
    > the loop doesn't end when i press enter without any input.
    > i guess (buffer[0] != '\0')) is wrong..
    >[/color]
    Yes
    The gets function reads a line from the standard input stream stdin and
    stores it in buffer. The line consists of all characters up to and including
    the first newline character ('\n'). gets then replaces the newline character
    with a null character ('\0') before returning the line. In contrast, the
    fgets function retains the newline character.
    You see?
    regards
    Robert



    Comment

    • Richard Bos

      #3
      Re: gets, fgets Question

      "herrcho" <herrcho2803@ko rnet.net> wrote:
      [color=blue]
      > int get_lines(char *lines[])
      > {
      > int n = 0;
      > char buffer[80];
      >
      > puts("Enter one line at time; enter a blank when done");
      >
      > while ((n < MAXLINES) && (gets(buffer) !=0 ) && (buffer[0] != '\0'))
      > {
      > if ((lines[n] = malloc(strlen(b uffer)+1)) == NULL)
      > return -1;
      > strcpy (lines[n++], buffer);
      > }
      > return n;
      > }
      >
      > the above code is from the book ' Teach yourself C '[/color]

      Ditch that book. Now. Any book teaching you to use gets() is a time
      bomb.
      [color=blue]
      > 1. gets(buffer) !=0 --> what does this mean ?
      > as far as i know, 'gets' function returns NULL when error occurs,[/color]

      No, it doesn't, since NULL is a part of your source code, not an object.
      When an error occurs (at least, an error that gets() is capable of
      detecting, the poor blind thing), gets() returns a null pointer.

      Now, the way to encode a null pointer in your code is to use a null
      pointer constant in a pointer context. Pointer context is simple:
      whenever something is compared or assigned to a pointer, that's a
      pointer context. In this case, gets() returns a pointer, and your 0 or
      NULL is compared to it, so that part's OK.

      A null pointer constant is either an integer constant with the value 0
      (0, or ('-'-'-'), or (!sizeof(char)) ...), or such an integer cast to
      void *. So 0 is a null pointer constant, and if you compare the return
      value of gets() to 0, what happens is that this null pointer constant is
      turned into a null pointer, and compared to the return value.
      Note that it is _not_ the other way around, as people sometimes think:
      no pointers are converted and then compared to a numerical 0. This is
      why, for example, this:

      int false_null_poin ter=0;
      if (fgets(x,y,z)== false_null_poin ter) ...

      is not guaranteed to work. It must be a null pointer _constant_.

      And NULL? NULL is simply a macro which is defined to be some null
      pointer constant. The implementation gets to choose which null pointer
      constant, but a valid null pointer constant, anyway.
      [color=blue]
      > either of them is alright ?[/color]

      NULL and 0 are equivalent in this (pointer) context, yes.
      [color=blue]
      > 2. I'd like to change the while statement using fgets.
      > so i tried the below
      >
      > while ((n < MAXLINES) && (fgets(buffer,8 0,stdin) !=0 ) &&
      > (buffer[0] != '\0'))
      > BUT !!
      > the loop doesn't end when i press enter without any input.
      > i guess (buffer[0] != '\0')) is wrong..[/color]

      Yes. fgets(), unlike gets(), always leaves the final '\n' in the buffer,
      if there is one. This is how you can tell whether fgets() read all input
      or returned because its buffer was full.
      [color=blue]
      > BTW ,, i saw a group, comp.lang.c.mod erated,, what's the difference ?[/color]

      Erm... c.l.c.m. is moderated?

      Richard

      Comment

      • John Bode

        #4
        Re: gets, fgets Question

        "herrcho" <herrcho2803@ko rnet.net> wrote in message news:<bkua3i$e1 k$1@news1.korne t.net>...[color=blue]
        > int get_lines(char *lines[])
        > {
        > int n = 0;
        > char buffer[80];
        >
        > puts("Enter one line at time; enter a blank when done");
        >
        > while ((n < MAXLINES) && (gets(buffer) !=0 ) && (buffer[0] != '\0'))
        > {
        > if ((lines[n] = malloc(strlen(b uffer)+1)) == NULL)
        > return -1;
        > strcpy (lines[n++], buffer);
        > }
        > return n;
        > }
        >
        > the above code is from the book ' Teach yourself C '[/color]

        Just to echo all the other responses, any book that advocates the use
        of gets() in any context is suspect. Putting gets() anywhere in your
        code introduces a point of failure.
        [color=blue]
        > it's for reading a row at a time, and if i just press enter without any
        > input, the loop terminates.
        >
        > Question..
        >
        > 1. gets(buffer) !=0 --> what does this mean ?
        > as far as i know, 'gets' function returns NULL when error occurs,
        > so it means gets(buffer) !=NULL ?
        > either of them is alright ?[/color]

        Essentially, yes. On a successful read, gets() will return the
        address of the buffer you're reading into. If it encounters an EOF or
        error on the standard input stream, it will return the null pointer
        value. A literal 0 in a pointer context is understood to represent
        the null pointer value.
        [color=blue]
        >
        > 2. I'd like to change the while statement using fgets.[/color]

        Good for you. It's safer than gets(), anyway.
        [color=blue]
        > so i tried the below
        >
        > while ((n < MAXLINES) && (fgets(buffer,8 0,stdin) !=0 ) &&
        > (buffer[0] != '\0'))
        > BUT !!
        > the loop doesn't end when i press enter without any input.
        > i guess (buffer[0] != '\0')) is wrong..[/color]

        Unlike gets(), fgets() stores the newline character as part of the
        array. So you'll need to change that test to

        (buffer[0] != '\0' && buffer[0] != '\n')
        [color=blue]
        >
        > Thanks in advance..
        >
        > BTW ,, i saw a group, comp.lang.c.mod erated,, what's the difference ?[/color]

        It's a moderated newsgroup, meaning messages are first examined by a
        moderator for content before they actually appear in the newsgroup.
        There's a FAQ on moderation...so mewhere...ah, here it is:



        In short, c.l.c.m doesn't suffer from endless flame wars, trolls, and
        general off-topic nonsense.

        Comment

        • Dan Pop

          #5
          Re: gets, fgets Question

          In <bkua3i$e1k$1@n ews1.kornet.net > "herrcho" <herrcho2803@ko rnet.net> writes:
          [color=blue]
          >int get_lines(char *lines[])
          >{
          > int n = 0;
          > char buffer[80];
          >
          > puts("Enter one line at time; enter a blank when done");
          >
          > while ((n < MAXLINES) && (gets(buffer) !=0 ) && (buffer[0] != '\0'))
          > {
          > if ((lines[n] = malloc(strlen(b uffer)+1)) == NULL)
          > return -1;
          > strcpy (lines[n++], buffer);
          > }
          > return n;
          >}
          >
          >the above code is from the book ' Teach yourself C '
          >it's for reading a row at a time, and if i just press enter without any
          >input, the loop terminates.[/color]

          Does the book also tell what happens when the user types 100 characters
          before pressing the Enter key?
          [color=blue]
          >Question..
          >
          >1. gets(buffer) !=0 --> what does this mean ?
          > as far as i know, 'gets' function returns NULL when error occurs,
          >so it means gets(buffer) !=NULL ?
          > either of them is alright ?[/color]

          Yes, provided one of the headers defining NULL has been included. NULL,
          however, makes your code more readable, so it is preferable to a naked 0.
          [color=blue]
          >2. I'd like to change the while statement using fgets.
          > so i tried the below
          >
          > while ((n < MAXLINES) && (fgets(buffer,8 0,stdin) !=0 ) &&
          >(buffer[0] != '\0'))
          > BUT !!
          > the loop doesn't end when i press enter without any input.
          > i guess (buffer[0] != '\0')) is wrong..[/color]

          Good guess! Make it (buffer[0] != '\n')). NEVER use a function before
          carefully reading its specification. gets/fgets and puts/fputs are
          tricky pairs.
          [color=blue]
          >BTW ,, i saw a group, comp.lang.c.mod erated,, what's the difference ?[/color]

          Being moderated, c.l.c.m has a lot less off-topic content, but the
          moderation process kills the response time: you post it today, it will
          show up tommorrow and the first responses will come the day after
          tomorrow. In the best case scenario, you get the first answers the
          next day, but still have to wait one more day, for reactions to the
          first "batch" of responses. In the "wild" c.l.c, you can have a full
          blown thread in a couple of hours.

          Dan
          --
          Dan Pop
          DESY Zeuthen, RZ group
          Email: Dan.Pop@ifh.de

          Comment

          • Barry Kimelman

            #6
            Re: gets, fgets Question

            On Thu, 25 Sep 2003 17:47:46 +0900, herrcho wrote:
            [color=blue]
            > int get_lines(char *lines[])
            > {
            > int n = 0;
            > char buffer[80];
            >
            > puts("Enter one line at time; enter a blank when done");
            >
            > while ((n < MAXLINES) && (gets(buffer) !=0 ) && (buffer[0] != '\0'))
            > {
            > if ((lines[n] = malloc(strlen(b uffer)+1)) == NULL)
            > return -1;
            > strcpy (lines[n++], buffer);
            > }
            > return n;
            > }
            >
            > the above code is from the book ' Teach yourself C '
            > it's for reading a row at a time, and if i just press enter without any
            > input, the loop terminates.
            >
            > Question..
            >
            > 1. gets(buffer) !=0 --> what does this mean ?
            > as far as i know, 'gets' function returns NULL when error occurs,
            > so it means gets(buffer) !=NULL ?[/color]
            Correct.
            [color=blue]
            > either of them is alright ?[/color]
            Yes. Either should work ok.
            [color=blue]
            >
            > 2. I'd like to change the while statement using fgets.
            > so i tried the below
            >
            > while ((n < MAXLINES) && (fgets(buffer,8 0,stdin) !=0 ) &&
            > (buffer[0] != '\0'))
            > BUT !!
            > the loop doesn't end when i press enter without any input.
            > i guess (buffer[0] != '\0')) is wrong..
            >
            > Thanks in advance..
            >
            > BTW ,, i saw a group, comp.lang.c.mod erated,, what's the difference ?[/color]

            while ( (n < MAXLINES) && (fgets(buffer,s izeof(buffer),s tdin)
            != 0 ) && (buffer[0] != '\n') ) {

            Comment

            • Tom Zych

              #7
              Re: gets, fgets Question

              herrcho wrote:
              [color=blue]
              > while ((n < MAXLINES) && (gets(buffer) !=0 ) && (buffer[0] != '\0'))[/color]

              No one else so far has explained exactly *why* gets() is poison
              (though Dan Pop hinted at it), and the FAQ doesn't seem to address
              it explicitly either, so burn this in 2-meter-high letters on your
              mind's eye:

              NEVER USE GETS()!!!

              gets() is one of those unfortunate things that really shouldn't be
              in C at all, but we're stuck with it. At least my compiler (gcc)
              always warns you not to use it. They all should. And the damned C
              books that fail to warn you about it should be set on fire, then
              stuffed into all of their authors' orifices. (Making an exception
              for the old ones like K&R, from before anyone knew how serious the
              problem was.)

              The thing about gets() is, it takes input directly from standard
              input, and it has no protection against buffer overflow. A very
              easily exploited combination.

              Let's say I know a certain program is running on your networked
              computer, and it uses gets() to read commands from the network; an
              email delivery daemon, for example. Suppose I have the source code
              of this program, and I know (or correctly guess) what kind of
              processor you're using. Let's say the programmer thought it would
              be safe to use a 512-byte buffer. No one would overflow such a
              long buffer, right?

              Not by accident, probably. But I'm going to do it on purpose,
              muhaha! With carefully crafted data. Which gets() will happily
              gulp, overflowing its buffer, and obligingly deposit in the memory
              beyond the buffer. Where its executable code is.

              Evil laugh. I now own your email program. And it's running with
              system privileges, so I own your system, too. This is not
              theoretical; crackers and worms have actually done this with
              programs that use gets(). The Great Worm, which infected 6,000
              large UNIX systems in 1988, exploited the use of gets() in a
              daemon (among other security holes).

              But, you're thinking, I'm just writing little test programs to
              learn C. True. No one's going to exploit your homework to break
              into your machine. But you really don't want to get into the habit
              of using this evil, evil function.

              So, to repeat:

              NEVER USE GETS()!!!

              --
              Tom Zych
              This is a fake email address to thwart spammers.
              Real address: echo 'gbzmlpu@cbobk. pbz' | rot13

              Comment

              • Dan Pop

                #8
                Re: gets, fgets Question

                In <3F73A949.D5D93 96A@pobox.com> Tom Zych <tznospam@pobox .com> writes:
                [color=blue]
                >herrcho wrote:
                >[color=green]
                >> while ((n < MAXLINES) && (gets(buffer) !=0 ) && (buffer[0] != '\0'))[/color]
                >
                >No one else so far has explained exactly *why* gets() is poison
                >(though Dan Pop hinted at it), and the FAQ doesn't seem to address
                >it explicitly either,[/color]

                When did they drop

                12.23: Why does everyone say not to use gets()?

                from the FAQ?

                Dan
                --
                Dan Pop
                DESY Zeuthen, RZ group
                Email: Dan.Pop@ifh.de

                Comment

                • Tom Zych

                  #9
                  Re: gets, fgets Question

                  Dan Pop wrote:
                  [color=blue]
                  > In <3F73A949.D5D93 96A@pobox.com> Tom Zych <tznospam@pobox .com> writes:[/color]
                  [color=blue][color=green]
                  > >No one else so far has explained exactly *why* gets() is poison
                  > >(though Dan Pop hinted at it), and the FAQ doesn't seem to address
                  > >it explicitly either,[/color][/color]
                  [color=blue]
                  > When did they drop
                  > 12.23: Why does everyone say not to use gets()?
                  > from the FAQ?[/color]

                  12.23 explains that the buffer may overflow. A newcomer to C may not
                  realize how dangerous this is. It sounds like an ordinary, everyday
                  bug, instead of a security-breaking, critical bug.

                  --
                  Tom Zych
                  This is a fake email address to thwart spammers.
                  Real address: echo 'gbzmlpu@cbobk. pbz' | rot13

                  Comment

                  • Peter Nilsson

                    #10
                    Re: gets, fgets Question

                    "Tom Zych" <tznospam@pobox .com> wrote in message
                    news:3F74464C.2 21318E8@pobox.c om...[color=blue]
                    > Dan Pop wrote:
                    >[color=green]
                    > > In <3F73A949.D5D93 96A@pobox.com> Tom Zych <tznospam@pobox .com> writes:[/color]
                    >[color=green][color=darkred]
                    > > >No one else so far has explained exactly *why* gets() is poison
                    > > >(though Dan Pop hinted at it), and the FAQ doesn't seem to address
                    > > >it explicitly either,[/color][/color]
                    >[color=green]
                    > > When did they drop
                    > > 12.23: Why does everyone say not to use gets()?
                    > > from the FAQ?[/color]
                    >
                    > 12.23 explains that the buffer may overflow. A newcomer to C may not
                    > realize how dangerous this is. It sounds like an ordinary, everyday
                    > bug, instead of a security-breaking, critical bug.[/color]

                    Why would a newbie think that an ordinary everyday bug was not worth
                    fixing?!

                    [I know why professionals dont! :-) I just don't understand why people who
                    still have shreads of ideals, and fewer time and budgetry constraints,
                    wouldn't consider it worth fixing. ;-)]

                    --
                    Peter


                    Comment

                    • Tom Zych

                      #11
                      Re: gets, fgets Question

                      Peter Nilsson wrote:
                      [color=blue]
                      > "Tom Zych" <tznospam@pobox .com> wrote in message
                      > news:3F74464C.2 21318E8@pobox.c om...[/color]
                      [color=blue][color=green]
                      > > 12.23 explains that the buffer may overflow. A newcomer to C may not
                      > > realize how dangerous this is. It sounds like an ordinary, everyday
                      > > bug, instead of a security-breaking, critical bug.[/color][/color]
                      [color=blue]
                      > Why would a newbie think that an ordinary everyday bug was not worth
                      > fixing?![/color]
                      [color=blue]
                      > [I know why professionals dont! :-) I just don't understand why people who
                      > still have shreads of ideals, and fewer time and budgetry constraints,
                      > wouldn't consider it worth fixing. ;-)][/color]

                      What 12.23 doesn't make sufficiently clear, IMHO, is that using
                      gets() is THE classic example of a bug that shouldn't be introduced
                      in the first place :)

                      --
                      Tom Zych
                      This is a fake email address to thwart spammers.
                      Real address: echo 'gbzmlpu@cbobk. pbz' | rot13

                      Comment

                      • Dan Pop

                        #12
                        Re: gets, fgets Question

                        In <3F7645EB.92399 2EE@pobox.com> Tom Zych <tznospam@pobox .com> writes:
                        [color=blue]
                        >Peter Nilsson wrote:
                        >[color=green]
                        >> "Tom Zych" <tznospam@pobox .com> wrote in message
                        >> news:3F74464C.2 21318E8@pobox.c om...[/color]
                        >[color=green][color=darkred]
                        >> > 12.23 explains that the buffer may overflow. A newcomer to C may not
                        >> > realize how dangerous this is. It sounds like an ordinary, everyday
                        >> > bug, instead of a security-breaking, critical bug.[/color][/color]
                        >[color=green]
                        >> Why would a newbie think that an ordinary everyday bug was not worth
                        >> fixing?![/color]
                        >[color=green]
                        >> [I know why professionals dont! :-) I just don't understand why people who
                        >> still have shreads of ideals, and fewer time and budgetry constraints,
                        >> wouldn't consider it worth fixing. ;-)][/color]
                        >
                        >What 12.23 doesn't make sufficiently clear, IMHO, is that using
                        >gets() is THE classic example of a bug that shouldn't be introduced
                        >in the first place :)[/color]

                        And what is the classical example of a bug that can be introduced in your
                        programs? ;-)

                        Dan
                        --
                        Dan Pop
                        DESY Zeuthen, RZ group
                        Email: Dan.Pop@ifh.de

                        Comment

                        Working...