问题 阅读popen会产生C ++


我正在编写一个C ++应用程序,我需要读取系统命令的结果。

我在用 popen() 或多或少如此处所示:

    const int MAX_BUFFER = 2048;
    string cmd="ls -l";
    char buffer[MAX_BUFFER];
    FILE *stream = popen(cmd.c_str(), "r");
    if (stream){
       while (!feof(stream))
       {
            if (fgets(buffer, MAX_BUFFER, stream) != NULL)
            {
               //here is all my code
            }
       }
       pclose(stream);
    }

我一直试图以不同的方式重写这个。我看到一些非标准的解决方案,如:

FILE *myfile;
std::fstream fileStream(myfile);
std::string mystring;
while(std::getline(myfile,mystring))
{
    // .... Here I do what I need
}

我的编译器不接受这个。

我该怎么读? popen 在C ++中?


2026
2017-10-18 13:12


起源

什么是 here all my code?如果是的话,你的第一个解决方案是完美的 data.append(buffer);。 - Beta
你可以从崩溃中发布调用堆栈吗? - Arkadiy
请提供最小的, 完成 程序,演示您的错误。从实际程序开始,删除所有有效的行,并向我们展示剩下的内容。 这里 是对第一个代码片段的工作实现的检查。看到 sscce.org 有关使用此技术的更多信息。 - Robᵩ
没有。如果结果为空,则会在fgets上崩溃 - Stefano
伙计们...我很抱歉......但你说得对...其他地方恐怖......我处于盲目模式,确定有错误,但事实并非如此!...感到非常抱歉一直坚持.. - Stefano


答案:


你的例子:

FILE *myfile;
std::fstream fileStream(myfile);
std::string mystring;
while(std::getline(myfile,mystring))

不起作用,因为虽然你非常接近,但标准库并没有提供 fstream 可以用a构建 FILE*提升iostreams 但是提供了一个 iostream 可以从文件描述符构造,你可以从一个 FILE* 通过电话 fileno

例如。:

typedef boost::iostreams::stream<boost::iostreams::file_descriptor_sink>
        boost_stream; 

FILE *myfile; 
// make sure to popen and it succeeds
boost_stream stream(fileno(myfile));
stream.set_auto_close(false); // https://svn.boost.org/trac/boost/ticket/3517
std::string mystring;
while(std::getline(stream,mystring))

别忘了 pclose 后来还是。

注意:较新版本的boost已弃用构造函数,只需要一个 fd。相反,你需要通过其中一个 boost::iostreams::never_close_handle 要么 boost::iostreams::close_handle 作为构造函数的强制性第二个参数。


15
2017-10-18 13:24



有些编译器为标准C ++库提供了非标准扩展。采用FILE *的fstream构造函数是一种流行的构造函数。这解释了为什么它适用于某些编译器而不适用于其他编译器。 - Sjoerd
@Sjoerd - 啊是的,这是有道理的。我想知道为什么会这样写。在构建工具中,您仍然可以使用typedef在配置时在非标准扩展和boost库之间进行选择。 - Flexo♦
我尝试使用fstream的标准构造函数但在我的情况下不被接受。我现在就这样试试...... - Stefano
没编译,我想接收器应该是源,因为它是一个只读的例子。提高::输入输出流:: file_descriptor_source - CyberSnoopy


这是我写回来的东西,可以帮助你。它可能有一些错误。

#include <vector>
#include <string>
#include <stdio.h>
#include <iostream>

bool my_popen (const std::string& cmd,std::vector<std::string>& out ) {
    bool            ret_boolValue = true;
    FILE*           fp;
    const int       SIZEBUF = 1234;
    char            buf [SIZEBUF];
    out = std::vector<std::string> ();
    if ((fp = popen(cmd.c_str (), "r")) == NULL) {
        return false;
    }
    std::string  cur_string = "";
    while (fgets(buf, sizeof (buf), fp)) {
        cur_string += buf;
    }
    out.push_back (cur_string.substr (0, cur_string.size () - 1));
    pclose(fp);
    return true;
}
int main ( int argc, char **argv) {
        std::vector<std::string> output;
        my_popen("ls -l > /dev/null ", output);
        for ( std::vector<std::string>::iterator itr = output.begin();
                                                 itr != output.end();
                                                 ++itr) {
                std::cout << *itr << std::endl;
        }

}

-5
2017-10-18 13:28