2011-10-18 6 views
11

私は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); 
    } 

:ここに示したように、私はpopen()は多かれ少なかれ使用してい

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

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

popenをC++で読むにはどうすればよいですか?

+0

「ここにすべてのコード」とは何ですか?あなたの最初のソリューションは 'data.append(buffer);'ならば完全に動作します。 – Beta

+1

あなたのクラッシュからコールスタックを公開できますか? – Arkadiy

+0

あなたのエラーを示す最小**完全**プログラムを提供してください。実際のプログラムから始めて、動作するすべての行を削除し、残っているものだけを表示してください。 [Here](http://ideone.com/azOcT)は、最初のコード断片を実装した実装の例です。このテクニックの使用の詳細については、http://sscce.orgを参照してください。 –

答えて

15

あなたの例:

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

Does't仕事あなたは非常に近いですが、標準ライブラリはFILE*から構築することができるfstreamが提供されていないため。 Boost iostreamsiostreamを提供しますが、これはファイル記述子から作成でき、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することを忘れないでください。

注:新しいバージョンのブーストでは、コンストラクタは単にfdになります。代わりに、boost::iostreams::never_close_handleまたはboost::iostreams::close_handleのいずれかをコンストラクタに必須の第2引数として渡す必要があります。

+0

標準のC++ライブラリに非標準の拡張機能を提供するコンパイラもあります。 FILE *をとるfstreamコンストラクタは一般的なものです。それはなぜそれが他のコンパイラではなくいくつかのコンパイラで動作する理由を説明します。 – Sjoerd

+0

@Sjoerd - ああ、それは意味をなさないでしょう。私はなぜそれがそのように書かれるのだろうと思った。ビルド・ツールでは、typedefを使用して、構成時に非標準拡張とブースト・ライブラリーの選択ができます。 – Flexo

+1

私はfstream用の標準コンストラクタを試しましたが、私の場合は受け入れられませんでした。私は今この方法で試してみます... – Stefano

-5

ここに私は長い時間を書きましたが、あなたを助けるかもしれません。いくつかのエラーがあるかもしれません。

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

} 
関連する問題