【问题标题】:Silencing stdout/stderr静音标准输出/标准错误
【发布时间】:2022-01-19 01:49:32
【问题描述】:

对于暂时silencing output to cout/cerr然后恢复它,什么是与this C++ answer 等效的C?

如何使stderr/stdout静音和恢复?

(需要这个来消除我正在调用的第 3 方库的噪音,并在通话后恢复。)

【问题讨论】:

  • 使用freopen()将他们重定向到/dev/null

标签: c++ c


【解决方案1】:

这是一个可怕的 hack,但应该可以:

#include <stdio.h>
#include <unistd.h>


int
suppress_stdout(void)
{
    fflush(stdout);
    int fd = dup(STDOUT_FILENO);
    freopen("/dev/null", "w", stdout);
    return fd;
}

void
restore_stdout(int fd)
{
    fflush(stdout);
    dup2(fd, fileno(stdout));
    close(fd);
}

int
main(void)
{
    puts("visible");
    int fd = suppress_stdout();
    puts("this is hidden");
    restore_stdout(fd);
    puts("visible");
}

【讨论】:

  • 为什么是 hack?我认为它正在确认 POSIX 规范.. 质疑在非 POSIX 系统上做什么。
  • 小吹牛:不应该是close(fd);最后在restore_stdout吗?我制作了一个适用于 Posix 和 Windows here 的版本 - 但由于某种原因,它实际上不适用于 Godbolt...
  • @user2052436 没有特别的原因。我相信任何一个都是正确的,但可能有教学上的理由更喜欢一个而不是另一个,所以我想我会证明两者。
  • @TedLyngmo 很好的建议。将编辑。
  • @TedLyngmo 因为打开“/dev/null”的权限被拒绝。我添加了错误处理和perror() 调用来跟踪它(这总是应该做的)。第一部分有效,但标准输出永远无效。也不确定程序如何解决这个问题,因为所需的 freopen ("/dev/stdout", "a", stdout); 也失败了 - 只存在读取权限。我猜他们的busybox或他们使用的任何东西都不支持,这个技巧适用于其他环境:wandbox、onlinegdb。
【解决方案2】:
#include <stdio.h>

#ifdef _WIN32
#define NULL_DEVICE "NUL:"
#define TTY_DEVICE "COM1:"
#else
#define NULL_DEVICE "/dev/null"
#define TTY_DEVICE "/dev/tty"
#endif

int main() {
    printf("hello!\n");

    freopen(NULL_DEVICE, "w", stdout);
    freopen(NULL_DEVICE, "w", stderr);

    printf("you CAN'T see this stdout\n");
    fprintf(stderr, "you CAN'T see this stderr\n");

    freopen(TTY_DEVICE, "w", stdout);
    freopen(TTY_DEVICE, "w", stderr);

    printf("you CAN see this stdout\n");
    fprintf(stderr, "you CAN see this stderr\n");
    return 0;
}

【讨论】:

  • 谢谢!两个问题:1)如何设置stdout/stderr恢复正常? 2) 是否有与操作系统无关的解决方案,而不仅仅是 Linux?
  • 这与操作系统无关;它是双重的。
  • 这仅适用于原始标准输出为 tty 的情况。这是一个可怕的假设。
  • 这只会将输出设置回“正常”,如果它要从 tty 开始,这是不能保证的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-11
  • 2014-07-22
  • 1970-01-01
  • 2013-01-11
  • 2011-11-30
  • 1970-01-01
相关资源
最近更新 更多