Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   whether is the standard input stream full buffered or line buffered after calling function setbuf()? (http://www.velocityreviews.com/forums/t439073-whether-is-the-standard-input-stream-full-buffered-or-line-buffered-after-calling-function-setbuf.html)

kernelxu@hotmail.com 08-14-2005 01:34 AM

whether is the standard input stream full buffered or line buffered after calling function setbuf()?
 
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


Walter Roberson 08-14-2005 02:18 AM

Re: whether is the standard input stream full buffered or line buffered after calling function setbuf()?
 
In article <1123983272.837369.23500@g47g2000cwa.googlegroups. com>,
<kernelxu@hotmail.com> 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.

kernelxu@hotmail.com 08-14-2005 07:48 AM

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.


Walter Roberson 08-14-2005 09:35 AM

Re: whether is the standard input stream full buffered or line buffered after calling function setbuf()?
 
In article <1124005728.145883.64950@z14g2000cwz.googlegroups. com>,
<kernelxu@hotmail.com> 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!

Netocrat 08-14-2005 12:16 PM

Re: whether is the standard input stream full buffered or line buffered after calling function setbuf()?
 
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


Eric Sosman 08-14-2005 12:36 PM

Re: whether is the standard input stream full buffered or line bufferedafter calling function setbuf()?
 
kernelxu@hotmail.com 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
esosman@acm-dot-org.invalid

kernelxu@hotmail.com 08-15-2005 05:50 AM

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 .


Dave Thompson 08-22-2005 04:01 AM

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), roberson@ibd.nrc-cnrc.gc.ca
(Walter Roberson) wrote:

> In article <1124005728.145883.64950@z14g2000cwz.googlegroups. com>,
> <kernelxu@hotmail.com> 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

Villy Kruse 08-22-2005 07:05 AM

Re: whether is the standard input stream full buffered or line buffered after calling function setbuf()?
 
On 14 Aug 2005 00:48:48 -0700,
kernelxu@hotmail.com <kernelxu@hotmail.com> 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

Michael Wojcik 08-23-2005 02:24 PM

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

In article <slrndgiu90.jl.vek@station02.ohout.pharmapartners. nl>, Villy Kruse <vek@station02.ohout.pharmapartners.nl> 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 michael.wojcik@microfocus.com

HTML is as readable as C. You can take this either way. -- Charlie Gibbs


All times are GMT. The time now is 02:43 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.