Чтение всплывающих результатов в C ++ - PullRequest
11 голосов
/ 18 октября 2011

Я пишу приложение на 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);
    }

Iпытался переписать это по-другому.Я видел некоторые нестандартные решения, такие как:

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

Мой компилятор не принимает это, хотя.

Как я могу читать из popen в C ++?

Ответы [ 2 ]

16 голосов
/ 18 октября 2011

Ваш пример:

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

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

0 голосов
/ 18 октября 2011

Вот то, что я написал давно, может помочь вам. Возможно, есть ошибки.

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

}
...