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

发布于 2025-01-17 02:13:24 字数 407 浏览 1 评论 0原文

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

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

my-ncurse-command | any-other-command
my-ncurse-command > some-stream

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

有办法允许吗? 谢谢。

I have a command that displays Ncurses stuffs (initscr, printw, addch, ...). That's okay.

At the end (endwin), I want to "output" (std::cout << "some string") a string to be processed by other command (or maybe redirected to a stream).
I want to do something like this :

my-ncurse-command | any-other-command
my-ncurse-command > some-stream

Problem is : my ncurses display is captured by the pipe or the redirect, not only the final string.

Is there a way to allow that ?
Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

少年亿悲伤 2025-01-24 02:13:24

使用 newterm(),而不是 initscr()。如果您已经在使用 newterm,那么只需提供与 stdout 不同的输出流即可。

initscr() 相当于:

#include <cstdlib>

WINDOW* myinitscr() {
    newterm(getenv("TERM"), stdout, stdin);
    return stdscr;
}

so

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

endwin() 之后:

std::fclose(cursesout);

或者,使用智能指针不必 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;
}

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

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

Instead of initscr(), use newterm(). If you are already using newterm it's just a matter of supplying a different output stream than stdout.

initscr() is equivalent to:

#include <cstdlib>

WINDOW* myinitscr() {
    newterm(getenv("TERM"), stdout, stdin);
    return stdscr;
}

so

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

and after endwin():

std::fclose(cursesout);

Alternatively, use a smart pointer to not have to std::fclose the new output stream manually:

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

A version not taking the address of a standard library function (which is strictly prohibited) could look like this:

#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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文