如何管道/重定向 NCurse 命令的最终标准输出?

Nee*_*bus 3 c++ unix ncurses

我有一个显示 Ncurses 内容的命令(initscrprintwaddch、 ...)。没关系。

在最后(endwin),我想“输出”(std::cout << "some string")一个字符串以供其他命令处理(或者可能重定向到流)。我想做这样的事情:

my-ncurse-command | any-other-command
my-ncurse-command > some-stream
Run Code Online (Sandbox Code Playgroud)

问题是:我的 ncurses 显示是由管道或重定向捕获的,而不仅仅是最终的字符串。

有办法允许吗?谢谢。

Ted*_*gmo 5

而不是initscr()使用newterm(). 如果您已经在使用,newterm那么只需提供与stdout.

initscr()相当于:

#include <cstdlib>

WINDOW* myinitscr() {
    newterm(getenv("TERM"), stdout, stdin);
    return stdscr;
}
Run Code Online (Sandbox Code Playgroud)

所以

#include <cstdio>
#include <cstdlib>

std::FILE* cursesout{};
WINDOW* myinitscr() {
    cursesout = std::fopen("/dev/tty", "w");   // open new stream to your terminal
    if(cursesout) newterm(std::getenv("TERM"), cursesout, stdin);
    return stdscr;
}
Run Code Online (Sandbox Code Playgroud)

之后endwin()

std::fclose(cursesout);
Run Code Online (Sandbox Code Playgroud)

或者,使用智能指针不必手动指向std::fclose新的输出流:

#include <cstdio>
#include <cstdlib>
#include <memory>

using FILE_ptr = std::unique_ptr<FILE, decltype(&std::fclose)>;
FILE_ptr cursesout{nullptr, nullptr};

WINDOW* myinitscr() {
    cursesout = FILE_ptr(std::fopen("/dev/tty", "w"), &std::fclose);
    if(cursesout) newterm(std::getenv("TERM"), cursesout.get(), stdin);
    return stdscr;
}
Run Code Online (Sandbox Code Playgroud)

不采用标准库函数地址(严格禁止)的版本可能如下所示:

#include <cstdio>
#include <cstdlib>
#include <memory>

using FILE_ptr = std::unique_ptr<FILE, void (*)(FILE*)>;
FILE_ptr cursesout{nullptr, nullptr};

WINDOW* myinitscr() {
    cursesout = FILE_ptr(std::fopen("/dev/tty", "w"), [](FILE* fp) {
        std::fclose(fp);
    });
    if(cursesout) newterm(std::getenv("TERM"), cursesout.get(), stdin);
    return stdscr;
}
Run Code Online (Sandbox Code Playgroud)