#include <stdio.h>
#include <stdlib.h>
int main()
{
char buf[1024];
int a,b;
int i;
setbuf(stdin, buf);
scanf("%d %d", &a, &b);
for(i=0; buf[i]!='\n'; i ){
putchar(buf[i]);
}
putchar('\n');
return 0;
}
When I input the values 1 2
, I used setbuf
to find out if the buffer was really cleared after reading the values.
When I printed out the buf
, however, the value I entered remained the same in buf
. That is, the output was 1 2
Why is this happening?
I would really appreciate if you could answer.
CodePudding user response:
Collating what is found in the comments, there's no guarantee that the libc implementation will clear the stdin
buffer. The FILE
structure could just keep a pointer to its current position within the buffer.
In addition, you need to change the size of the buffer to BUFSIZ
and make it so that its lifetime is for the rest of the program. According to the C11 standard:
The buffer has to have a lifetime at least as great as the open stream, so the stream should be closed before a buffer that has automatic storage duration is deallocated upon block exit.
This can be accomplished by either making the buffer global or declaring it to be static
:
static char buf[BUFSIZ];
CodePudding user response:
Here is what the C Standard says about function setbuf()
:
7.21.5.5 The
setbuf
functionSynopsis
#include <stdio.h> void setbuf(FILE * restrict stream, char * restrict buf);
Description
Except that it returns no value, the
setbuf
function is equivalent to thesetvbuf
function invoked with the values_IOFBF
formode
andBUFSIZ
forsize
, or (ifbuf
is a null pointer), with the value_IONBF
formode
.Returns
Thesetbuf
function returns no value.
7.21.5.6 The
setvbuf
functionSynopsis
#include <stdio.h> int setvbuf(FILE * restrict stream, char * restrict buf, int mode, size_t size);
Description
The
setvbuf
function may be used only after the stream pointed to bystream
has been associated with an open file and before any other operation (other than an unsuccessful call tosetvbuf
) is performed on the stream. The argumentmode
determines how stream will be buffered, as follows:_IOFBF
causes input/output to be fully buffered;_IOLBF
causes input/output to be line buffered;_IONBF
causes input/output to be unbuffered. Ifbuf
is not a null pointer, the array it points to may be used instead of a buffer allocated by thesetvbuf
function277) and the argumentsize
specifies the size of the array; otherwise,size
may determine the size of a buffer allocated by thesetvbuf
function. The contents of the array at any time are indeterminate.Returns
The
setvbuf
function returns zero on success, or nonzero if an invalid value is given formode
or if the request cannot be honored.
277) The buffer has to have a lifetime at least as great as the open stream, so the stream should be closed before a buffer that has automatic storage duration is deallocated upon block exit.
It follows that:
- The array
buf
in your code should have a length ofBUFSIZ
- This array should not have automatic storage class because
stdin
is not closed before the functionmain
returns. It should be defined asstatic char buf[BUFSIZ];
- the buffer may or may not be used by the stream handling functions
- The contents of the array at any time are indeterminate, hence nothing can be expected about the buffer contents: you observe that the user input is present, but this is not guaranteed. Most implementations have pointers or offsets in the
FILE
structure to keep track of used and available portions of the buffer. - It is highly unlikely that stream handling functions clear the buffer contents after reading the bytes, because it would prevent require reloading the buffer from the file in case of seeking back over previous contents, but again there is no guarantee about this either.
setbuf
is a legacy function with limited use, setvbuf
is preferred to select the buffering mode and buffer size.