whether is the standard input stream full buffered or line buffered after calling function setbuf()

Discussion in 'C Programming' started by kernelxu@hotmail.com, Aug 14, 2005.

  1. Guest

    hi,everybody.
    I calling function setbuf() to change the characteristic of standsrd
    input buffer.
    some fragment of the progrem is:
    (DEV-C++2.9.9.2)
    #include <stdio.h>
    #include <stdlib.h>
    int main(void)
    {
    char buf[10] = {0};
    int i;
    int j;
    char c;

    setbuf(stdin, buf);
    c = getchar();
    for(j = 0; j < 10; j++)
    {
    printf("%d ",buf[j]);
    j++;
    }
    printf("\n over \n");

    return 0;
    }

    the following questions confused me for a long time.
    1) how to judge whether the standard input stream is full buffered or
    line buffered .what about it after calling the function setbuf(stdin,
    buf)?

    2) when I enter an letter 'a', the result is
    97 10 10 0 0 0 0 0 0 0
    where does the second '10' come from? does it due to the OS(I use
    Windows 2000 professional)?

    3)how does the system flush the buffers of I/O streams? are there any
    differences between flushing input buffer and output buffer?

    4)If I calling setbuf(stdin, (char *)0) to set the input buffer as no
    buffer, does it work for all standard input functions or just for one
    function near to it, for example:

    /*DEV-C++*/
    #include <stdio.h>

    int main(void)
    {
    int i,j;
    char c;

    setbuf(stdin, (char *)0); /* 1 */

    printf("\n do you want to cal:y/n \n");
    while ((c = getchar()) == 'y')
    {
    printf("input number:\n");
    scanf("%d%d", &i, &j);
    printf("i*j = %ld", i*j);
    setbuf(stdin, (char *)0); /* 2*/
    printf("\n do you want to cal:y/n \n");
    }

    return 0;
    }

    should I select 1 or 2, though the first doesn't work? but why?

    mang many questions, I am so confused on streams and buffers.
    any help will be appreciated deeply.

    kernelxu
     
    , Aug 14, 2005
    #1
    1. Advertising

  2. In article <>,
    <> wrote:
    >I calling function setbuf() to change the characteristic of standsrd
    >input buffer.


    >#include <stdio.h>
    >#include <stdlib.h>
    >int main(void)
    >{
    > char buf[10] = {0};
    > int i;
    > int j;
    > char c;
    >
    > setbuf(stdin, buf);
    > c = getchar();
    > for(j = 0; j < 10; j++)
    > {
    > printf("%d ",buf[j]);
    > j++;
    > }
    > printf("\n over \n");
    >
    > return 0;
    >}


    >the following questions confused me for a long time.
    >1) how to judge whether the standard input stream is full buffered or
    > line buffered .what about it after calling the function setbuf(stdin,
    >buf)?


    In order to determine the kind of buffering that a particular
    stream has, one must use system-specific measures.


    >2) when I enter an letter 'a', the result is
    >97 10 10 0 0 0 0 0 0 0
    >where does the second '10' come from? does it due to the OS(I use
    >Windows 2000 professional)?


    That 10 are the decimal representation of newline characters.

    Note: I do not have my copy of the C89 standard here. The online
    man page I am looking at suggests that in your program, the last
    8 bytes of the supplied buffer, buf[2] thru buf[9], are used for
    internal purposes rather than to store characters. If that is the
    case, then the second 10 might be an artifact rather than an entered byte.


    >3)how does the system flush the buffers of I/O streams?


    The FILE* data structure includes overhead information to indicate
    the portion of the buffer that is used. The flush operation passes
    that data to the operating system; the details of how it does that
    are operating system dependant and subject to change without notice.

    > are there any
    >differences between flushing input buffer and output buffer?


    Yes. In standard C, the operation of flushing an input buffer is not
    defined.


    >4)If I calling setbuf(stdin, (char *)0) to set the input buffer as no
    >buffer, does it work for all standard input functions or just for one
    >function near to it,


    All operations on that stream, until the stream is closed or
    set*buf* called again.

    >#include <stdio.h>
    >int main(void)
    >{
    > int i,j;
    > char c;
    > setbuf(stdin, (char *)0); /* 1 */
    > printf("\n do you want to cal:y/n \n");
    > while ((c = getchar()) == 'y')
    > {
    > printf("input number:\n");
    > scanf("%d%d", &i, &j);
    > printf("i*j = %ld", i*j);
    > setbuf(stdin, (char *)0); /* 2*/
    > printf("\n do you want to cal:y/n \n");
    > }
    > return 0;
    >}


    >should I select 1 or 2, though the first doesn't work? but why?


    You only need once.

    If the first "doesn't work" then I can suggest a possible reason.
    When you do the scanf(), the newline after the two numbers "conflicts"
    with the %d format in order to terminate the reading of the number.
    That newline is "left unread in the input stream". When you then do
    the getchar(), that newline is going to be what is read, and it
    isn't going to be 'y' so the while is going to terminate.

    In the same vein: you generally need to enter a newline after the initial
    'y' because although the input might not be "buffered" by the time it
    gets to your program, it might be buffered at the shell -- setting
    stdin to be unbuffered is *not* the same as undertaking system-
    specific methods to turn on "raw" mode. This newline after the 'y'
    is not happening to cause you problems because when you scanf() for i and j,
    scanf is defined to skip -leading- whitespace -- and newline is
    considered whitespace.

    It is easy to fall into the habit of thinking that scanf()
    starts at the beginning of the current line and "consumes" the
    newline at the end, but it's just the opposite: it "consumes"
    the -prior- newlines and leaves the -current- lineline in the buffer
    (unless your format specifically asks for it.)
    --
    Ceci, ce n'est pas une idée.
     
    Walter Roberson, Aug 14, 2005
    #2
    1. Advertising

  3. Guest

    Re: whether is the standard input stream full buffered or line buffered after calling function setbuf()?

    thank you very much, Walter.
    Walter says:
    >In order to determine the kind of buffering that a particular
    >stream has, one must use system-specific measures.

    so, if I assumed the standard input stream is line buffered, is it
    still line buffered after calling "setbuf(stdin, buf)" ? on the other
    word, the difference between setbuf() and
    setvbuf() is that the latter can change the buffer mode but the former
    can't.


    >Note: I do not have my copy of the C89 standard here. The online
    >man page I am looking at suggests that in your program, the last
    >8 bytes of the supplied buffer, buf[2] thru buf[9], are used for
    >internal purposes rather than to store characters. If that is the
    >case, then the second 10 might be an artifact rather than an entered byte.

    I can't understand it completely, would you please give me some webpage
    links such as
    the man page you have found?


    >Yes. In standard C, the operation of flushing an input buffer is not
    >defined.

    and,if I change the standard input buffer into my own buffer, is it
    defined when I flush it?
    for instance:

    #include <stdio.h>
    int main(void)
    {
    int i,j;
    char c;
    char my_buf[256];

    setbuf(stdin, my_buf);

    printf("\n do you want to cal:y/n \n");
    while ((c = getchar()) == 'y')
    {
    printf("input number:\n");
    scanf("%d%d", &i, &j);
    printf("i*j = %ld", i*j);
    fflush(stdin);
    printf("\n do you want to cal:y/n \n");
    }

    return 0;
    }

    The program works or not due to specific system. it is fine on
    Windows2000+DEV-C++, but somebody tell me it fails on his system( I
    don't the details, but it does fail).


    >In the same vein: you generally need to enter a newline after the initial
    >'y' because although the input might not be "buffered" by the time it
    >gets to your program, it might be buffered at the shell -- setting
    >stdin to be unbuffered is *not* the same as undertaking system-
    >specific methods to turn on "raw" mode. This newline after the 'y'
    >is not happening to cause you problems because when you scanf() for i and j,
    >scanf is defined to skip -leading- whitespace -- and newline is
    >considered whitespace.

    the problem becomes more and more complex, what should I do on earth
    when confronted with input problem relevant with the buffer?
    is it a good idea by calling setbuf() or setvbuf()?
    or, are there any other efficient methods?

    thank you very much ! looking forward to your reply.
     
    , Aug 14, 2005
    #3
  4. Re: whether is the standard input stream full buffered or line buffered after calling function setbuf()?

    In article <>,
    <> wrote:

    >Walter says:
    >>In order to determine the kind of buffering that a particular
    >>stream has, one must use system-specific measures.


    >so, if I assumed the standard input stream is line buffered,


    That is not a safe assumption; input will only be line buffered if
    it has been set to be line buffered. The default for input is fully
    buffered.

    >is it
    >still line buffered after calling "setbuf(stdin, buf)" ?


    According to the [SGI IRIX] manual page I am looking at, if buf
    is NULL then the I/O will be unbuffered, and otherwise it will
    be line-buffered if the stream is associated with a terminal.

    >on the other
    >word, the difference between setbuf() and
    >setvbuf() is that the latter can change the buffer mode but the former
    >can't.


    No, setbuf() changes the mode, but A) has no way to force line
    buffering (to a non-terminal); B) has no way to force full
    buffering (to a terminal); and C) assumes that the buffer
    is a particular minimum size whereas the size is a parameter
    for setvbuf().


    >>. In standard C, the operation of flushing an input buffer is not
    >>defined.


    >and,if I change the standard input buffer into my own buffer, is it
    >defined when I flush it?


    No. The C standard only defines flushing output buffers.
    fflush(stdin) will NOT work on most systems.


    >>This newline after the 'y'
    >>is not happening to cause you problems because when you scanf() for i and j,
    >>scanf is defined to skip -leading- whitespace -- and newline is
    >>considered whitespace.


    >the problem becomes more and more complex, what should I do on earth
    >when confronted with input problem relevant with the buffer?


    The default buffering works well in most situations, and
    many of the rest of the situations can be dealt with by
    flushing output at key locations.

    Your problems are not with buffering: your problems are with
    not understanding how to handle newlines.
    --
    This signature intentionally left... Oh, darn!
     
    Walter Roberson, Aug 14, 2005
    #4
  5. Netocrat Guest

    On Sun, 14 Aug 2005 08:36:08 -0400, Eric Sosman wrote:

    [...]
    > Unless your implementation's BUFSIZ is ten or less (I've never
    > encountered so small a value)


    C89 requires it to be at least 256.

    --
    http://members.dodo.com.au/~netocrat
     
    Netocrat, Aug 14, 2005
    #5
  6. Eric Sosman Guest

    Re: whether is the standard input stream full buffered or line bufferedafter calling function setbuf()?

    wrote:

    > hi,everybody.
    > I calling function setbuf() to change the characteristic of standsrd
    > input buffer.
    > some fragment of the progrem is:
    > (DEV-C++2.9.9.2)
    > #include <stdio.h>
    > #include <stdlib.h>
    > int main(void)
    > {
    > char buf[10] = {0};
    > int i;
    > int j;
    > char c;
    >
    > setbuf(stdin, buf);


    This is wrong. The second argument to setbuf() must either
    be NULL or must point to an area of at least BUFSIZ characters.
    Unless your implementation's BUFSIZ is ten or less (I've never
    encountered so small a value), your program goes completely off
    the rails right here.

    > c = getchar();
    > for(j = 0; j < 10; j++)
    > {
    > printf("%d ",buf[j]);
    > j++;
    > }
    > printf("\n over \n");
    >
    > return 0;


    This is wrong, too. You've asked stdin to use a buffer
    that will cease to exist as soon as main() returns, but when
    main() returns stdin is still "alive" and hasn't been closed.
    If any shutting-down operations try to make use of the now-
    vanished buffer, there's no telling what could happen. (True,
    this is usually more troublesome for output streams than for
    input, but you're begging for trouble.)

    --
    Eric Sosman
    lid
     
    Eric Sosman, Aug 14, 2005
    #6
  7. Guest

    Re: whether is the standard input stream full buffered or line buffered after calling function setbuf()?

    Walter, Eric and Netocrat
    Thank you very much.
    the view instantly clears up .
     
    , Aug 15, 2005
    #7
  8. Re: whether is the standard input stream full buffered or line buffered after calling function setbuf()?

    On Sun, 14 Aug 2005 09:35:11 +0000 (UTC), -cnrc.gc.ca
    (Walter Roberson) wrote:

    > In article <>,
    > <> wrote:
    >
    > >Walter says:
    > >>In order to determine the kind of buffering that a particular
    > >>stream has, one must use system-specific measures.

    >
    > >so, if I assumed the standard input stream is line buffered,

    >
    > That is not a safe assumption; input will only be line buffered if
    > it has been set to be line buffered. The default for input is fully
    > buffered.
    >

    According to the standard, the default for stdin (and out) is fully
    buffered 'if and only if the stream can be determined not to refer to
    an interactive device'. But it can be hard or even impossible for an
    implementation to make this determination accurately, so it's best not
    to assume either way.

    > >is it
    > >still line buffered after calling "setbuf(stdin, buf)" ?

    >
    > According to the [SGI IRIX] manual page I am looking at, if buf
    > is NULL then the I/O will be unbuffered, and otherwise it will
    > be line-buffered if the stream is associated with a terminal.
    >

    NULL certainly must make it unbuffered at the C-library level, and a
    valid buf (as already noted should be BUFSIZ not 10) fully buffered.
    However, terminal input is line-oriented in most OS'es, including
    AFAIK IRIX, so full has same effect as line. (As you correctly
    explained in another thread by I believe the same OP!)

    > >on the other
    > >word, the difference between setbuf() and
    > >setvbuf() is that the latter can change the buffer mode but the former
    > >can't.

    >
    > No, setbuf() changes the mode, but A) has no way to force line
    > buffering (to a non-terminal); B) has no way to force full
    > buffering (to a terminal); and C) assumes that the buffer
    > is a particular minimum size whereas the size is a parameter
    > for setvbuf().
    >

    A yes. B it does set full buffering _in C_ which should be effective
    _to_ a terminal (on stdout, or stderr or other) but as above on most
    systems not for input. C yes.

    <snip rest>

    - David.Thompson1 at worldnet.att.net
     
    Dave Thompson, Aug 22, 2005
    #8
  9. Villy Kruse Guest

    Re: whether is the standard input stream full buffered or line buffered after calling function setbuf()?

    On 14 Aug 2005 00:48:48 -0700,
    <> wrote:


    > thank you very much, Walter.
    > Walter says:
    >>In order to determine the kind of buffering that a particular
    >>stream has, one must use system-specific measures.

    > so, if I assumed the standard input stream is line buffered, is it
    > still line buffered after calling "setbuf(stdin, buf)" ? on the other
    > word, the difference between setbuf() and
    > setvbuf() is that the latter can change the buffer mode but the former
    > can't.
    >
    >


    What is the assumed difference between stdin being line buffered or fully
    buffered? I would assume that in either case the stdio functions will
    get whatever is available from the OS on every read. If the OS gives
    you one line at a time, then that is what you get, but if it is like
    unix and windows, just gives you a unstructured byte streadm there is
    no way you can force the OS to give you data one line at a time.

    Villy
     
    Villy Kruse, Aug 22, 2005
    #9
  10. Re: whether is the standard input stream full buffered or line buffered after calling function setbuf()?

    In article <>, Villy Kruse <> writes:
    >
    > What is the assumed difference between stdin being line buffered or fully
    > buffered? I would assume that in either case the stdio functions will
    > get whatever is available from the OS on every read.


    The implementation will likely "get whatever is available", but if
    stdin is line buffered it should only return it to the caller if it
    encounters a line terminator (or any condition it interprets as an
    error or end-of-file). And if stdin is fully buffered, it should
    only return data to the caller when the buffer is full (or it gets an
    error or EOF).

    > If the OS gives
    > you one line at a time, then that is what you get, but if it is like
    > unix and windows, just gives you a unstructured byte streadm there is
    > no way you can force the OS to give you data one line at a time.


    There's no need to force the OS to do anything. The implementation
    does the buffering. When you call fgets(), the implementation is
    free to wait until doomsday to return, if it wants to wait for a line
    terminator or some other condition.

    --
    Michael Wojcik

    HTML is as readable as C. You can take this either way. -- Charlie Gibbs
     
    Michael Wojcik, Aug 23, 2005
    #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. Replies:
    9
    Views:
    3,167
    Walter Roberson
    Aug 22, 2005
  2. Replies:
    9
    Views:
    640
    Alex Buell
    Apr 27, 2006
  3. Kashif Ur Rehman
    Replies:
    2
    Views:
    867
    Tom Hawtin
    May 17, 2007
  4. Richard Maher
    Replies:
    4
    Views:
    578
  5. markspace
    Replies:
    6
    Views:
    320
    Arne Vajhøj
    Nov 7, 2011
Loading...

Share This Page