代码之家  ›  专栏  ›  技术社区  ›  Rick Jim DeLaHunt

为什么scanf可以读取超过1024个字符,而stdin流缓冲区只有1024个字节?

  •  1
  • Rick Jim DeLaHunt  · 技术社区  · 6 年前

    stdin 在Ubuntu下连接我终端的流缓冲区大小和缓冲区类型,由源代码决定 阿普 :

    #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);
    }
    

    stream = stdin, line buffered, buffer size = 1024


    然后我写一个测试:

    #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;
    }
    

    我将1440(>1024字节)字符“1”粘贴到终端,并期望以某种方式丢弃多余的输入数据,因为行缓冲区大小只有1024字节。但最终,我得到了“1”的印刷品 c[1033]

    为什么可以 scanf 读取超过1024个字符,而缓冲区大小为 标准

    引自 阿普

    我们可以看到,这个系统的默认设置是标准输入和标准输出 输出线连接到终端时缓冲。行缓冲区为1024 请注意,这并没有将我们限制为1024字节的输入和输出行;这只是 缓冲区的大小。

    或者我该问问怎么做?

    对于每个输入

    0 回复  |  直到 6 年前
        1
  •  3
  •   Jonathan Leffler    6 年前

    如评论中所述 scanf() 到达第一个缓冲区已满的结尾,如果它仍然需要更多的数据,它将返回到系统以获取更多的数据,可能是多次。缓冲区只是一种方便和优化的措施。