当前位置: 首页 > 知识库问答 >
问题:

在控制台应用程序中运行外部文本编辑器-C++

吕向阳
2023-03-14

我正在用C++构建一个控制台应用程序,需要一种方法来调用终端文本编辑器,以满足用户的编辑乐趣,并知道何时完成。

例如,在git中,当您运行git rebase-interactive时,它会在终端中启动一个文本编辑器(默认情况下是Nano),您可以轻松地在其中编辑提交。当您关闭编辑器时,git将继续在控制台中进行操作。

我相信我需要做的是将一个编辑器作为子进程启动,不断地通过cincout传递给它,最后在编辑器退出时恢复程序。

我研究了popen,但它只发送一个流(stdout)。我甚至通读了Git的重基实现,但搞不清楚他们是怎么做到的。

有什么建议吗?

共有1个答案

漆雕升
2023-03-14

如何调用编辑器取决于系统。在Unix系统上,您将生成一个进程,并将标准输入、标准输出和标准错误传递给子进程,因为可能所有这三个进程都连接到终端。如果不重定向这些流,这通常是默认行为。

这通常是通过使用fork和Unix上的exec*系列函数之一来完成的,但也可以使用posix_spawn系列函数。在Windows上有不同的方法。

如果已设置visual环境变量,并且term设置为dumb以外的其他内容,则应使用该环境变量,否则应使用editor;如果两者都未设置,则返回到系统默认值(通常为vi)。这些环境变量的值必须始终传递给/bin/sh(如果不是POSIX sh,则传递给POSIX sh)以求值;例如,将visualeditor设置为f(){vim“$0”“$@”;};f总是可以接受的,并且使用这些变量的所有程序都必须支持这一点。Git也会做同样的事情,还会在其他位置搜索编辑器。

下面是一个粗略的C(和有效的C++)程序,它什么也不做,只是通过命令行中的参数生成一个编辑器。它应该大致演示如何正确生成编辑器:

#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

bool is_dumb(void)
{
    const char *term = getenv("TERM");
    return !term || !strcmp(term, "dumb");
}

const char *editor(void)
{
    const char *ed = NULL;
    if (!is_dumb())
        ed = getenv("VISUAL");
    if (!ed)
        ed = getenv("EDITOR");
    if (!ed)
        ed = "vi";
    return ed;
}

int main(int argc, char **argv)
{
    const char *ed = editor();
    pid_t pid = fork();
    if (pid < 0) {
        perror("Failed to spawn editor");
        exit(127);
    }
    if (!pid) {
        const char *append = " \"$@\"";
        size_t len = strlen(ed) + strlen(append) + 1;
        char *final_editor = (char *)malloc(len);
        snprintf(final_editor, len, "%s%s", ed, append);
        const char **args = (const char **)malloc(sizeof(const char *) * (argc + 3));
        if (!args)
            exit(255);
        args[0] = "sh";
        args[1] = "-c";
        args[2] = final_editor;
        for (int i = 1; i < argc; i++)
            args[i + 2] = argv[i];
        args[argc + 2] = NULL;
        execvp("sh", (char *const *)args);
        exit(127);
    } else {
        int wstatus;
        waitpid(pid, &wstatus, 0);
        if (WIFEXITED(wstatus)) {
            exit(wstatus);
        } else {
            exit(255);
        }
    }
}
 类似资料:
  • 我试图在中运行控制台应用程序,但出现错误。 异常“yii\base\UnknownPropertyException”,在F:\xampp\htdocs\mdc\vendor\yiisoft\yii2\base\Component中显示消息“设置未知属性:yii\console\Response::formatters”。菲律宾比索:209 Common\config\main本地。php Cro

  • 问题内容: 我已经开发了一个Java控制台应用程序,该应用程序在启动时打开控制台窗口并保持在前台,我想在后台启动该应用程序。 现在,我通过以下命令行启动该应用程序: 有没有办法实现这种行为?更改命令行参数就足够了,还是我需要对代码进行一些更改? 问题答案: 答案取决于操作系统。

  • 我有一台服务器(Ubuntu 14.04.4 LTS),并希望某个Java应用程序一直在其上运行。目前我使用

  • 在JupyterLab中,我希望将代码从编辑器发送到Python控制台执行,最好使用键盘快捷键。文档似乎没有提供实现这一点的方法,但它是IDE的一个基本方面,我认为这是可能的。

  • 我发现Atom编辑器是Sublime文本编辑器的免费替代品。无法找到在Atom编辑器中运行程序的简单方法。在我的例子中,我试图运行一个java程序。如果可能的话请告诉我如果是,请说明应采取的步骤。

  • 通过WebLogic Admin控制台停止/启动部署时,有时我们会收到以下错误: 然而,如果我停止并启动托管服务器,部署似乎又回来了。 我的问题是,为什么这些war文件在服务器运行时从托管服务器上随机消失?这通常发生在我们有一段时间(6个月)没有接触部署之后。还有其他部署的war文件。它不会影响应用程序的运行,直到我们尝试停止/启动它。 这就是文件系统前后的样子。 在此处重新启动托管服务器。。。