popen()函数将执行命令的输出写入到cout中。

8

我正在编写一个需要打开另一个进程并获取其输出的应用程序。在网上阅读的所有内容都说我必须使用 popen 并从文件中读取。

但是我无法从中读取。命令的输出被输出到调用应用程序的控制台窗口。以下是我正在使用的代码。我添加了一些打印信息进行调试。

#include <string>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <array>

int main()
{
    // some command that fails to execute properly.
    std::string command("ls afskfksakfafkas");

    std::array<char, 128> buffer;
    std::string result;

    std::cout << "Opening reading pipe" << std::endl;
    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe)
    {
        std::cerr << "Couldn't start command." << std::endl;
        return 0;
    }
    while (fgets(buffer.data(), 128, pipe) != NULL) {
        std::cout << "Reading..." << std::endl;
        result += buffer.data();
    }
    auto returnCode = pclose(pipe);

    std::cout << result << std::endl;
    std::cout << returnCode << std::endl;

    return 0;
}

我在cout中并没有看到任何输出,结果是一个空字符串。我可以在终端上清楚地看到命令的输出。如果命令正常退出,则行为符合预期。但只有在错误情况下才捕获输出。


使用feof()来控制循环是不好的实践,在您的情况下毫无意义,因为fgets()在文件结束时返回NULL。尝试提供一个[MCVE],让人们可以重现您的问题。如果您不知道问题是什么,那么像您提供部分信息是留下关键信息的好方法。很可能您正在运行的命令使用的是一种输出方式,该方式不能使用您的技术进行重定向。 - Peter
@Peter 提供完整的示例。我只是添加了int main并添加了一个硬编码命令... - user2882307
2个回答

12

Popen无法捕获标准错误,只能捕获标准输出。将标准错误重定向到标准输出可以解决该问题。

#include <string>
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <array>

int main()
{
    std::string command("ls afskfksakfafkas 2>&1");

    std::array<char, 128> buffer;
    std::string result;

    std::cout << "Opening reading pipe" << std::endl;
    FILE* pipe = popen(command.c_str(), "r");
    if (!pipe)
    {
        std::cerr << "Couldn't start command." << std::endl;
        return 0;
    }
    while (fgets(buffer.data(), 128, pipe) != NULL) {
        std::cout << "Reading..." << std::endl;
        result += buffer.data();
    }
    auto returnCode = pclose(pipe);

    std::cout << result << std::endl;
    std::cout << returnCode << std::endl;

    return 0;
}

7

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接