web-dev-qa-db-ja.com

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
}

私のコンパイラはこれを受け入れません。

C++でpopenから読み取るにはどうすればよいですか?

11
Stefano

あなたの例:

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

標準ライブラリはFILE*から構築できるfstreamを提供していないため、機能しません。 Boost iostreams は、ファイル記述子から構築できるiostreamを提供します。また、filenoを呼び出すことでFILE*から取得できます。

例えば。:

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のみを使用するコンストラクターが非推奨になりました。代わりに、コンストラクターへの必須の2番目の引数としてboost::iostreams::never_close_handleまたはboost::iostreams::close_handleのいずれかを渡す必要があります。

16
Flexo