C - 如何抑制子函数的输出?

时间:2022-12-26 06:09:02

I want to call bar() in foo(), bar() will change some global variables' values(this is what I want), but meanwhile produce some output( I dont' want any output);

我想在foo()中调用bar(),bar()会改变一些全局变量的值(这就是我想要的),但同时产生一些输出(我不想要任何输出);

void foo() 
{
    //I have tried:
    //system("1>&/dev/null") and of course this won't work
    bar();
}

What can I do to suppress bar()'s output?

我该怎么做才能抑制bar()的输出?

1 个解决方案

#1


14  

You can save the global variable stdout before bar();, then set it to /dev/null, then restore it. Code example;

您可以在bar();之前保存全局变量stdout,然后将其设置为/ dev / null,然后将其还原。代码示例;

#include <stdio.h>

int main() {
    int old_stdout = dup(1);

    freopen ("/dev/null", "w", stdout); // or "nul" instead of "/dev/null"
    printf("asd1");
    fclose(stdout);

    stdout = fdopen(old_stdout, "w"); 
    printf("asd2");
    return 0;
}

Tested on OS X, not sure about Windows.

在OS X上测试,不确定Windows。

EDIT: You can replace /dev/null with nul on Windows. As for the fdopen() and dup() working under Windows - they're part of the POSIX.1 standard according to my man pages, but I haven't tested it.

编辑:您可以在Windows上用nul替换/ dev / null。至于在Windows下工作的fdopen()和dup() - 根据我的手册页,它们是POSIX.1标准的一部分,但我还没有测试过它。

EDIT 2: As suggested in the comments, if the solution does not work for Windows, there's another suggestion in this SO answer.

编辑2:正如评论中所建议的,如果解决方案不适用于Windows,那么这个SO答案中还有另一个建议。

EDIT 3: A longer, though standard compliant and cross-platform way to do this is as following. (code adapted from mentioned SO question, and Microsoft's documentation for _dup)

编辑3:更长,但标准兼容和跨平台的方式来做到这一点如下。 (代码改编自提到的SO问题,以及Microsoft的_dup文档)

#include <stdio.h>

#ifdef _WIN32
#include <io.h>
char * const nulFileName = "NUL";
#define CROSS_DUP(fd) _dup(fd)
#define CROSS_DUP2(fd, newfd) _dup2(fd, newfd)
#else
#include <unistd.h>
char * const nulFileName = "/dev/null";
#define CROSS_DUP(fd) dup(fd)
#define CROSS_DUP2(fd, newfd) dup2(fd, newfd)
#endif

int main() {
    int stdoutBackupFd;
    FILE *nullOut;
    /* duplicate stdout */
    stdoutBackupFd = CROSS_DUP(STDOUT_FILENO);

    fflush(stdout);
    nullOut = fopen(nulFileName, "w");
    CROSS_DUP2(fileno(nullOut), STDOUT_FILENO);

    printf("asd1\n");
    fflush(stdout);
    fclose(nullOut);

    // Restore stdout
    CROSS_DUP2(stdoutBackupFd, STDOUT_FILENO);
    close(stdoutBackupFd);

    printf("asd2\n");

    return 0;
}

The flushes are required to make sure that (1) anything printed before switching stdout is indeed printed to screen, and (2) nothing that was printed before switching back stdout to console (or pipe) is printed.

需要刷新以确保(1)在切换stdout之前打印的任何内容确实打印到屏幕上,以及(2)在将stdout切换回控制台(或管道)之前没有打印任何内容。

#1


14  

You can save the global variable stdout before bar();, then set it to /dev/null, then restore it. Code example;

您可以在bar();之前保存全局变量stdout,然后将其设置为/ dev / null,然后将其还原。代码示例;

#include <stdio.h>

int main() {
    int old_stdout = dup(1);

    freopen ("/dev/null", "w", stdout); // or "nul" instead of "/dev/null"
    printf("asd1");
    fclose(stdout);

    stdout = fdopen(old_stdout, "w"); 
    printf("asd2");
    return 0;
}

Tested on OS X, not sure about Windows.

在OS X上测试,不确定Windows。

EDIT: You can replace /dev/null with nul on Windows. As for the fdopen() and dup() working under Windows - they're part of the POSIX.1 standard according to my man pages, but I haven't tested it.

编辑:您可以在Windows上用nul替换/ dev / null。至于在Windows下工作的fdopen()和dup() - 根据我的手册页,它们是POSIX.1标准的一部分,但我还没有测试过它。

EDIT 2: As suggested in the comments, if the solution does not work for Windows, there's another suggestion in this SO answer.

编辑2:正如评论中所建议的,如果解决方案不适用于Windows,那么这个SO答案中还有另一个建议。

EDIT 3: A longer, though standard compliant and cross-platform way to do this is as following. (code adapted from mentioned SO question, and Microsoft's documentation for _dup)

编辑3:更长,但标准兼容和跨平台的方式来做到这一点如下。 (代码改编自提到的SO问题,以及Microsoft的_dup文档)

#include <stdio.h>

#ifdef _WIN32
#include <io.h>
char * const nulFileName = "NUL";
#define CROSS_DUP(fd) _dup(fd)
#define CROSS_DUP2(fd, newfd) _dup2(fd, newfd)
#else
#include <unistd.h>
char * const nulFileName = "/dev/null";
#define CROSS_DUP(fd) dup(fd)
#define CROSS_DUP2(fd, newfd) dup2(fd, newfd)
#endif

int main() {
    int stdoutBackupFd;
    FILE *nullOut;
    /* duplicate stdout */
    stdoutBackupFd = CROSS_DUP(STDOUT_FILENO);

    fflush(stdout);
    nullOut = fopen(nulFileName, "w");
    CROSS_DUP2(fileno(nullOut), STDOUT_FILENO);

    printf("asd1\n");
    fflush(stdout);
    fclose(nullOut);

    // Restore stdout
    CROSS_DUP2(stdoutBackupFd, STDOUT_FILENO);
    close(stdoutBackupFd);

    printf("asd2\n");

    return 0;
}

The flushes are required to make sure that (1) anything printed before switching stdout is indeed printed to screen, and (2) nothing that was printed before switching back stdout to console (or pipe) is printed.

需要刷新以确保(1)在切换stdout之前打印的任何内容确实打印到屏幕上,以及(2)在将stdout切换回控制台(或管道)之前没有打印任何内容。