【问题标题】:Read in while loop读入while循环
【发布时间】:2019-01-15 11:01:25
【问题描述】:

我一直试图围绕缓冲区和依赖它们的 I/O 函数展开思考,当我遇到这段 sn-p 代码时,起初看起来很直观,但一旦我开始使用它,我得到的结果出乎意料。

我使用了一个while循环来read()来自标准输入的每一行,printf()打印出我读到的内容。几次输入后,打印输出开始变得怪异,似乎关闭了,因为知道read() 每次调用它都会覆盖目标缓冲区。

char line[256];
int n;

while((n = read(STDIN_FILENO, line, 256) > 0)
    printf("%s", line);

在第三次拍摄 (abcdefghj) 时,printf 似乎开始混合结果。

abc
abc
abcdef
abcdef
abcdefghj
cdeabcdefghj

【问题讨论】:

    标签: c io buffer


    【解决方案1】:

    read 用于读取“原始字节”而不是字符串,这样它就不会以字符串终止字符\0 来终止输入。如果您将结果打印到控制台,如果您运气好(或坏?),缓冲区已用0 初始化,这样您实际上会收到一个字符串输出。

    但是如果第二行比读入的第一行短,您将只覆盖第一行内容的一部分,并将其余部分与第二行一起再次打印出来。

    写...

    while (fgets(line, 256,STDIN_FILENO)) {
       fputs(line,stdout);
       ...
    }
    

    一切正常。

    【讨论】:

      【解决方案2】:

      read 不会在字符串末尾添加 '\0' 终止符 - 您需要自己执行此操作,例如

      while((count = read(STDIN_FILENO, line, 255) > 0)
      {                                    // ^^^ NB: need to allow room for terminator !
          line[count] = '\0';
          printf("%s", line);
      }
      

      或者你也可以告诉printf要打印多少个字符而不用担心终结符:

      while((count = read(STDIN_FILENO, line, 256) > 0)
      {                                    
          printf("%.*s\n", count, s);
      }
      

      【讨论】:

      • 啊,所以如果没有空字节,printf 也会打印出任何传递的内容?基本上它不知道什么时候停止?
      • @monolith937:是的,完全正确。
      猜你喜欢
      • 1970-01-01
      • 2013-07-08
      • 1970-01-01
      • 2011-03-05
      • 2017-03-05
      • 2015-01-04
      • 2018-04-17
      • 2017-10-12
      • 1970-01-01
      相关资源
      最近更新 更多