#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
setbuffunctionSynopsis
#include <stdio.h> void setbuf(FILE * restrict stream, char * restrict buf);Description
Except that it returns no value, the
setbuffunction is equivalent to thesetvbuffunction invoked with the values_IOFBFformodeandBUFSIZforsize, or (ifbufis a null pointer), with the value_IONBFformode.Returns
Thesetbuffunction returns no value.
7.21.5.6 The
setvbuffunctionSynopsis
#include <stdio.h> int setvbuf(FILE * restrict stream, char * restrict buf, int mode, size_t size);Description
The
setvbuffunction may be used only after the stream pointed to bystreamhas been associated with an open file and before any other operation (other than an unsuccessful call tosetvbuf) is performed on the stream. The argumentmodedetermines how stream will be buffered, as follows:_IOFBFcauses input/output to be fully buffered;_IOLBFcauses input/output to be line buffered;_IONBFcauses input/output to be unbuffered. Ifbufis not a null pointer, the array it points to may be used instead of a buffer allocated by thesetvbuffunction277) and the argumentsizespecifies the size of the array; otherwise,sizemay determine the size of a buffer allocated by thesetvbuffunction. The contents of the array at any time are indeterminate.Returns
The
setvbuffunction returns zero on success, or nonzero if an invalid value is given formodeor 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
bufin your code should have a length ofBUFSIZ - This array should not have automatic storage class because
stdinis not closed before the functionmainreturns. 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
FILEstructure 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.
