簡體   English   中英

靜音標准輸出/標准錯誤

[英]Silencing stdout/stderr

什么是 C 等效於這個 C++ 的答案,用於暫時將 output 靜音到 cout/cerr然后恢復它?

如何將失敗狀態設置為stderr/stdout

(需要這個來消除我正在呼叫的第 3 方庫的噪音,並在呼叫后恢復。)

這是一個可怕的黑客,但應該工作:

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

int
main(void)
{
        puts("visible");
        int fd = suppress_stdout();
        puts("this is hidden");
        restore_stdout(fd);
        puts("visible");
}
freopen("/dev/null", "w", stdout);
freopen("/dev/null", "w", stderr);

這是一種純 C 方法,沒有操作系統依賴項。

C 2018 7.21.1 2 說<stdio.h>聲明了一個FILE類型,能夠記錄控制 stream 所需的所有信息。 這表明我們可以復制FILE object 以保存控制 stream 所需的一切。

因此,我們可以復制*stdout*stderr的內容來保存它們,用我們選擇的 stream 替換它們,然后再恢復它們。

下面創建一個 stream 並關閉它,然后將關閉的 stream 用於stdoutstderr ,將所有stderr操作留給stdout和。 如果希望 output 操作不會遇到不必要的錯誤,我們可以打開兩個臨時文件並保持打開狀態,直到不再需要為止。

#include <stdio.h>
#include <stdlib.h>


int main(void)
{
    //  Save the original stdout and stderr.
    FILE Saved[] = { *stdout, *stderr };

    //  Create a new stream with a temporary file that is automatically removed.
    FILE *Dummy = tmpfile();
    if (!Dummy)
    {
        fprintf(stderr, "Error, unable to open temporary file.\n");
        exit(EXIT_FAILURE);
    }

    //  Close the dummy stream.
    fclose(Dummy);

    //  Replace stdout and stderr with the dead stream.
    *stdout = *Dummy;
    *stderr = *Dummy;

    //  Attempt to write to stdout and stderr.
    printf("Hello, world.\n");
    fprintf(stderr, "This does not work.\n");

    //  Restore the original stdout and stderr.
    *stdout = Saved[0];
    *stderr = Saved[1];

    //  Write to the original stdout and stderr.
    printf("I'm back!\n");
    fprintf(stderr, "No errors here.\n");
}

Output:

I'm back!
No errors here.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM