I can get stdin
stream buffer size and buffer type that connected my terminal under Ubuntu, by the code from APUE:
#include "apue.h" //It's merely a wrapper header
void pr_stdio(const char *, FILE *);
int is_unbuffered(FILE *);
int is_linebuffered(FILE *);
int buffer_size(FILE *);
int
main(void)
{
FILE *fp;
fputs("enter any character\n", stdout);
if (getchar() == EOF)
err_sys("getchar error");
fputs("one line to standard error\n", stderr);
pr_stdio("stdin", stdin);
pr_stdio("stdout", stdout);
pr_stdio("stderr", stderr);
if ((fp = fopen("/etc/passwd", "r")) == NULL)
err_sys("fopen error");
if (getc(fp) == EOF)
err_sys("getc error");
pr_stdio("/etc/passwd", fp);
exit(0);
}
void
pr_stdio(const char *name, FILE *fp)
{
printf("stream = %s, ", name);
if (is_unbuffered(fp))
printf("unbuffered");
else if (is_linebuffered(fp))
printf("line buffered");
else /* if neither of above */
printf("fully buffered");
printf(", buffer size = %d\n", buffer_size(fp));
}
int
is_unbuffered(FILE *fp)
{
return(fp->_flags & _IO_UNBUFFERED);
}
int
is_linebuffered(FILE *fp)
{
return(fp->_flags & _IO_LINE_BUF);
}
int
buffer_size(FILE *fp)
{
return(fp->_IO_buf_end - fp->_IO_buf_base);
}
Run the code above from terminal I got: stream = stdin, line buffered, buffer size = 1024
.
Then I write a test:
#include "stdio.h"
int main(){
char c[2048];
c[1033] = 'a';
scanf("%s", c); //I paste 1440 '1' into the terminal.
printf("%c", c[1033]); //I expect it to be 'a'.
return 0;
}
I paste 1440(>1024 byte) character '1' to the terminal and expect excess input data would be discarded somehow, for the line buffer size is only 1024 byte. But eventually, I got '1' printed with c[1033]
.
Why can scanf
read more than 1024 character while buffer size of stdin
is 1024B only?
Quoted from APUE:
We can see that the default for this system is to have standard input and standard output line buffered when they’re connected to a terminal. The line buffer is 1,024 bytes. Note that this doesn’t restrict us to 1,024-byte input and output lines; that’s just the size of the buffer. Writing a 2,048-byte line to standard output will require two write system calls.
Or maybe should I ask how?
I don't understand the emphasized text much. Doesn't a buffer restrict user input size? Why it says I can input more than buffer size data (for each input)? Could someone tell me that how does it work?
As noted in a comment, when scanf()
gets to the end of the first buffer full, if it still needs more data, it goes back to the system to get more, possibly many times. The buffer is merely a convenience and optimization measure.