char* gets(char* buffer)

Discussion in 'C Programming' started by Sathyaish, Oct 5, 2004.

  1. Sathyaish

    Sathyaish Guest

    I noticed that gets() reads into the buffer even if the you've not
    allocated enough memory. For instance, if you do:

    Code:
    char *str=(char*)malloc(sizeof(char));
    printf("Enter something about yourself below:\n\n");
    gets(str);
    printf("\n\n");
    puts(str);
    
    This works without a problem even though I initialized the buffer with
    a single char only for the heck of it. Of course, not initializing the
    char pointer at all will definitely result in a crash. For instance,
    doing just this definitely would result in a null-pointer exception
    and would crash the program.

    Code:
    char *str
    printf("Enter something about yourself below:\n\n");
    gets(str);
    printf("\n\n");
    puts(str);
    
    So, my question is whether with gets(), unlike most other C functions
    where we the programmers are supposed to make good guesses as to the
    amount of memory we need, can we just get away without caring about
    the length of the buffer required?

    If I explicity say,

    Code:
    char str[1000];
    printf("Enter something about yourself below:\n\n");
    gets(str);
    printf("\n\n");
    puts(str);
    
    I explcitiy define the length of the buffer I would be using, but
    gets() keeps returning input even if it exceeds the 999 characters I
    expected.

    The documentation here

    http://www.cplusplus.com/ref/cstdio/gets.html

    says:


    Please shed some light on this function's behaviour as regards buffer
    allocation.
    Sathyaish, Oct 5, 2004
    #1
    1. Advertising

  2. In article <>,
    Sathyaish <> wrote:
    >I noticed that gets() reads into the buffer even if the you've not
    >allocated enough memory. For instance, if you do:


    [snip]

    >Please shed some light on this function's behaviour as regards buffer
    >allocation.


    There's no way to avoid overwriting memory if the input is longer than
    you expect. This means that it's impossible to use gets without creating
    a bug that allows a buffer overrun.
    The solution is to Don't Do That. Use something like
    fgets(buf,sizeof buf,stdin)
    instead if longer-than-expected input is an error (if the string you
    get back doesn't include a '\n', either you have an input error or the
    buffer is full and the rest of the line is still waiting in the input),
    or google for ggets in posts here if input needs to be arbitrarily sized.


    dave

    --
    Dave Vandervies
    But people who write sloppy code tend to find other avenues of expressing
    that, anyway.
    --Micah Cowan in comp.lang.c
    Dave Vandervies, Oct 5, 2004
    #2
    1. Advertising

  3. Sathyaish

    Mabden Guest

    "Dave Vandervies" <> wrote in message
    news:cjuojk$5r8$...
    > In article <>,
    > Sathyaish <> wrote:
    > >I noticed that gets() reads into the buffer even if the you've not
    > >allocated enough memory. For instance, if you do:

    >
    > [snip]
    >
    > >Please shed some light on this function's behaviour as regards buffer
    > >allocation.

    >
    > There's no way to avoid overwriting memory if the input is longer than
    > you expect. This means that it's impossible to use gets without

    creating
    > a bug that allows a buffer overrun.
    > The solution is to Don't Do That. Use something like
    > fgets(buf,sizeof buf,stdin)
    > instead if longer-than-expected input is an error (if the string you
    > get back doesn't include a '\n', either you have an input error or the
    > buffer is full and the rest of the line is still waiting in the

    input),
    > or google for ggets in posts here if input needs to be arbitrarily

    sized.
    >


    I don't really see the need for a gets() or fgets(). It's just a loop to
    do getc() for you, so why not just do it yourself and _know_ what is
    going on. I'm generally looking for more than just the newline char when
    I'm parsing data so I just read a char at a time. I mean, aren't you
    going to go through the string (or line) you just inputted anyway?
    What's the point of parsing it twice?

    --
    Mabden
    Mabden, Oct 5, 2004
    #3
  4. Sathyaish

    Default User Guest

    Sathyaish wrote:

    > So, my question is whether with gets(), unlike most other C functions
    > where we the programmers are supposed to make good guesses as to the
    > amount of memory we need, can we just get away without caring about
    > the length of the buffer required?


    No.


    http://www.eskimo.com/~scs/C-faq/q12.23.html




    Brian Rodenborn
    Default User, Oct 5, 2004
    #4
  5. (Sathyaish) writes:
    > I noticed that gets() reads into the buffer even if the you've not
    > allocated enough memory.


    Which invokes undefined behavior, which (if you're unlucky) can
    manifest itself as your program not exhibiting any visible problems.

    Never use gets().

    This is question 12.23 of the C FAQ,
    <http://www.eskimo.com/~scs/C-faq/top.html>.

    --
    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, Oct 5, 2004
    #5
  6. Sathyaish

    Eric Sosman Guest

    Mabden wrote:
    > "Dave Vandervies" <> wrote in message
    > news:cjuojk$5r8$...
    >
    >>In article <>,
    >>Sathyaish <> wrote:
    >>
    >>>I noticed that gets() reads into the buffer even if the you've not
    >>>allocated enough memory. For instance, if you do:

    >>
    >>[snip]
    >>
    >>
    >>>Please shed some light on this function's behaviour as regards buffer
    >>>allocation.

    >>
    >>There's no way to avoid overwriting memory if the input is longer than
    >>you expect. This means that it's impossible to use gets without

    >
    > creating
    >
    >>a bug that allows a buffer overrun.
    >>The solution is to Don't Do That. Use something like
    >> fgets(buf,sizeof buf,stdin)
    >>instead if longer-than-expected input is an error (if the string you
    >>get back doesn't include a '\n', either you have an input error or the
    >>buffer is full and the rest of the line is still waiting in the

    >
    > input),
    >
    >>or google for ggets in posts here if input needs to be arbitrarily

    >
    > sized.
    >
    >
    > I don't really see the need for a gets() or fgets(). It's just a loop to
    > do getc() for you, so why not just do it yourself and _know_ what is
    > going on. I'm generally looking for more than just the newline char when
    > I'm parsing data so I just read a char at a time. I mean, aren't you
    > going to go through the string (or line) you just inputted anyway?
    > What's the point of parsing it twice?


    Convenience. getc() gives you only one character of
    look-ahead (because you can have only one ungetc()'d char
    outstanding), so if you need more you'll need to manage
    some kind of buffer anyhow.

    Convenience. Once you've found a sequence of interesting
    input characters you may want to do something with them, and
    many of the "somethings" involve calling C library functions
    like strcmp() or strtod() or even sscanf(), all of which
    need to see the entire string at once.

    Convenience is certainly not the be-all and end-all of
    programming, but there's much to be said for it. Who among
    us has not used the convenient printf(...) instead of the
    equivalent but clumsier fprintf(stdout,...)? Who has not
    used printf() when puts() would have done the job?

    There are plenty of situations where character-by-character
    input is preferable: You can handle Really Long Lines without
    requiring Really Big Buffers, you can change your mind in
    mid-stream before reading too far ahead (scanf() couldn't
    be implemented atop fgets(), for example), and so on. But
    in situations where these aren't of great concern, fgets()
    is simply ... convenient.

    (By the way, I'm not suggesting that fgets() is perfect.
    Its return value is particularly annoying, as it tells you
    something you already knew instead of something you didn't,
    something that fgets() has figured out that you may need to
    figure out all over again. fgets() is blemished -- but so
    are we all, says my theology professor.)

    --
    Eric Sosman, Oct 5, 2004
    #6
  7. Sathyaish

    Mike Wahler Guest

    "Mabden" <mabden@sbc_global.net> wrote in message
    news:doC8d.7081$...
    > "Dave Vandervies" <> wrote in message
    > news:cjuojk$5r8$...
    > > In article <>,
    > > Sathyaish <> wrote:
    > > >I noticed that gets() reads into the buffer even if the you've not
    > > >allocated enough memory. For instance, if you do:

    > >
    > > [snip]
    > >
    > > >Please shed some light on this function's behaviour as regards buffer
    > > >allocation.

    > >
    > > There's no way to avoid overwriting memory if the input is longer than
    > > you expect. This means that it's impossible to use gets without

    > creating
    > > a bug that allows a buffer overrun.
    > > The solution is to Don't Do That. Use something like
    > > fgets(buf,sizeof buf,stdin)
    > > instead if longer-than-expected input is an error (if the string you
    > > get back doesn't include a '\n', either you have an input error or the
    > > buffer is full and the rest of the line is still waiting in the

    > input),
    > > or google for ggets in posts here if input needs to be arbitrarily

    > sized.
    > >

    >
    > I don't really see the need for a gets() or fgets(). It's just a loop to
    > do getc() for you,


    'gets()' and 'fgets()' might be implemented by invoking
    'getc()', but AFAIK, they're not required to. They might
    call 'lower level' OS functions directly (which would
    typically have better performance than 'getc()', if only
    because one level of abstraction is eliminated). As long as
    the *behavior* conforms to the standard, the implementation
    is left to the implementor.

    -Mike
    Mike Wahler, Oct 5, 2004
    #7
  8. Sathyaish

    Xenos Guest

    "Mabden" <mabden@sbc_global.net> wrote in message
    news:doC8d.7081$...

    > I don't really see the need for a gets() or fgets(). It's just a loop to
    > do getc() for you, so why not just do it yourself and _know_ what is
    > going on. I'm generally looking for more than just the newline char when
    > I'm parsing data so I just read a char at a time. I mean, aren't you
    > going to go through the string (or line) you just inputted anyway?
    > What's the point of parsing it twice?
    >

    Because sometimes you want to decouple the input retrieval from the parser.
    Xenos, Oct 5, 2004
    #8
  9. Sathyaish

    Sathyaish Guest

    Thanks, Dave.



    (Dave Vandervies) wrote in message news:<cjuojk$5r8$>...
    > In article <>,
    > Sathyaish <> wrote:
    > >I noticed that gets() reads into the buffer even if the you've not
    > >allocated enough memory. For instance, if you do:

    >
    > [snip]
    >
    > >Please shed some light on this function's behaviour as regards buffer
    > >allocation.

    >
    > There's no way to avoid overwriting memory if the input is longer than
    > you expect. This means that it's impossible to use gets without creating
    > a bug that allows a buffer overrun.
    > The solution is to Don't Do That. Use something like
    > fgets(buf,sizeof buf,stdin)
    > instead if longer-than-expected input is an error (if the string you
    > get back doesn't include a '\n', either you have an input error or the
    > buffer is full and the rest of the line is still waiting in the input),
    > or google for ggets in posts here if input needs to be arbitrarily sized.
    >
    >
    > dave
    Sathyaish, Oct 5, 2004
    #9
  10. Sathyaish

    CBFalconer Guest

    Dave Vandervies wrote:
    > Sathyaish <> wrote:
    >
    >> I noticed that gets() reads into the buffer even if the you've
    >> not allocated enough memory. For instance, if you do:

    >
    > [snip]
    >
    >> Please shed some light on this function's behaviour as regards
    >> buffer allocation.

    >
    > There's no way to avoid overwriting memory if the input is longer
    > than you expect. This means that it's impossible to use gets
    > without creating a bug that allows a buffer overrun.
    > The solution is to Don't Do That. Use something like
    > fgets(buf,sizeof buf,stdin)
    > instead if longer-than-expected input is an error (if the string
    > you get back doesn't include a '\n', either you have an input
    > error or the buffer is full and the rest of the line is still
    > waiting in the input), or google for ggets in posts here if
    > input needs to be arbitrarily sized.


    ggets is available at:

    <http://cbfalconer.home.att.net/download/ggets.zip>

    --
    Chuck F () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
    CBFalconer, Oct 5, 2004
    #10
    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. Stefan Mueller
    Replies:
    5
    Views:
    504
    Steven Saunderson
    Jul 10, 2006
  2. lovecreatesbeauty
    Replies:
    1
    Views:
    1,003
    Ian Collins
    May 9, 2006
  3. John Joyce

    gets gets

    John Joyce, Mar 26, 2007, in forum: Ruby
    Replies:
    2
    Views:
    330
    John Joyce
    Mar 26, 2007
  4. John Joyce

    Return of gets gets

    John Joyce, Apr 23, 2007, in forum: Ruby
    Replies:
    0
    Views:
    178
    John Joyce
    Apr 23, 2007
  5. libsfan01
    Replies:
    5
    Views:
    227
    Jeff North
    Dec 20, 2006
Loading...

Share This Page