【问题标题】:setbuf redirectionsetbuf 重定向
【发布时间】:2011-08-16 21:27:33
【问题描述】:

我使用 setbuf 将标准输出重定向到字符缓冲区 但是之后我得到了一些副作用,当我只想将新数据写入标准输出时

如下代码所述:

#define bufSize  100
int main()
{
    char buf[bufSize];
    setbuf(stdout, buf);
    printf("123");             //123 is written to the buffer

    setbuf(stdout,NULL);       //123 is written to the stdout(unwanted side effect)
    printf("456");             //123456 appears in the stdout
}

我该如何解决这个问题?

关于此的其他问题 - 此代码是否适用于 unix/linux/mac os?

谁能提出重定向的解决方案?

【问题讨论】:

  • 我猜你必须先刷新缓冲区,然后才能将其设置为其他内容。
  • @cnicutar,它有点帮助。但没有解决问题 - 从第 4 个位置开始在标准输出中打印 456(我的意思是 123 结束的地方,还有一个差距......)跨度>
  • 标准 C99 中没有办法将流重定向到自动增长的缓冲区。 TR27431-2 中有一些类似要求的机制,但它们并非在任何地方都可用。我也不确定他们是否将其纳入即将发布的 C 标准。

标签: c redirect buffer stdout


【解决方案1】:

setbuf() 函数不会将输出重定向到缓冲区。它只是告诉标准 I/O 库“使用这个缓冲区;不要自己分配一个”。

您还应该在每个打开的流中使用一次setbuf()(在它打开之后和对其进行任何其他操作之前),然后不要管它。如果您多次使用它,您就会陷入未定义的行为 - 您看到的内容是可以接受的,因为所需的行为是未定义的。

C99 标准说:

§7.19.5.5 setbuf 函数

除了不返回值外,setbuf函数等价于setvbuf 使用值 _IOFBF 表示模式和 BUFSIZ 表示大小调用的函数,或者(如果 buf 是一个空指针),其值为 _IONBF 表示模式。

§7.19.5.6 setvbuf 函数

setvbuf 函数只能在 stream 指向的流具有 与打开的文件相关联并且在任何其他操作之前(除了 在流上执行对 setvbuf) 的不成功调用。

【讨论】:

  • setbuf(stdout, NULL) 将自己分配一个缓冲区。
  • @duedl0r:不,不会。它将设置非缓冲输出。请参阅标准的引用,提及_IONBF
  • 是的,你可能是对的,这没有任何意义。我从man setbuf 读到以下内容:“如果参数buf 为NULL,则只有模式受到影响;我们在下一次读取或写入操作时分配了一个新缓冲区。”这让我很困惑。如果您考虑一下,使用 _IONBF 不需要缓冲区。但话又说回来,前面的短语是什么意思?也许这意味着分配了一个缓冲区,但立即刷新?
【解决方案2】:

我认为您不能将stdout 重定向到这样的缓冲区。无论如何,它最终会出现在stdout。您只需指定一个将由您的流使用的缓冲区。

如果您使用setbuf(stdout, NULL),它将在后台创建一个新缓冲区。它将是无缓冲的写入..即不需要刷新。

所以这里没有副作用,只是正常行为。


如果您想重定向stdout,请查看here。前两个答案描述了两种技术。

【讨论】:

  • 如何正确解决上述重定向问题?
【解决方案3】:

setbuf 不用于重定向。除了关闭缓冲之外,它基本上没用,所以所有输出都会立即出现。它也可以用来给stdio一个不同的缓冲区,它可以用于FILE,但它没有义务以任何特定的方式使用它,而且由于stdio通常使用它自己的大小合适的缓冲区,我看不到提供自己的缓冲区如何非常有用。

如果您想重定向输出,您可能应该提出一个新问题,以便更好地准确描述您想要获得的效果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-05
    • 2019-09-15
    • 2018-01-24
    • 2013-09-11
    • 1970-01-01
    相关资源
    最近更新 更多