Чтение результатов 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++?

2 ответов


ваш пример:

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

не работает, потому что, хотя вы очень близки стандартная библиотека не предоставляет fstream это может быть построено из 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 в качестве обязательного второго аргумента конструктора.


вот что я написал давно, может вам помочь. Там могут быть ошибки.

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

}