私のプログラムから別のプログラムからの出力を読み取る必要があります。そのために、popen()を使用できます。このようにして、プログラムで解析できるファイル*をプログラムの出力に取得します。プログラムからpopen()の戻り値の内容を読み取って解析するにはどうすればよいですか?あるいは、どこかにもっとC ++のようなバージョンのpopenがありますか?
2 に答える
と道徳的に等価なストリーム バッファを作成するかpopen()
、ストリーム バッファ ラッピングを作成することができますFILE*
。ストリーム バッファを取得したら、目的とstd::istream
思われる方法で使用できます。からの単純な (そしてテストされていない) ストリーム バッファの読み取りは、次のFILE*
ようになります。
struct FILEbuf
: std::streambuf {
FILEbuf(FILE* fp): fp_(fp) {}
int underflow() {
if (this->gptr() == this->egptr()) {
int size = fread(this->buffer_, 1, s_size, this->fp_);
if (0 < size) {
this->setg(this->buffer_, this->buffer_, this->buffer_ + size);
}
}
return this->gptr() == this->egptr()
? traits_type::eof()
: traits_type::to_int_type(*gptr());
}
FILE* fp_;
enum { s_size = 1024 };
char buffer_[s_size];
};
何かを間違って入力したと思いますが、大まかに言えば、アイデアはうまくFILE*
いきます。または、生成されたプロセスから読み取るストリームを作成します。これには、プラットフォーム固有のfork()
, exec..()
, pipe()
,への呼び出しが 2 回必要ですclose()
がdup2()
(おそらくここでも何かを忘れている可能性があります)、同様に実行できます。
上記のようなストリーム バッファは、たとえば次のように使用できます。
int main()
{
FILEbuf sbuf(fopen("pstream.cpp", "r"));
std::istream in(&sbuf);
for (std::string line; std::getline(in, line); ) {
std::cout << line << '\n';
}
}
(GNU実装)またはFILE*
と呼ばれるC++ラッパーがあります。標準化されたものではないと思いますが、グーグルで検索すると、多くのプラットフォームで利用できることがわかります。から返され、gcc 4.5.0でコンパイルされ、Linuxボックスでテストされたポインターでそれを使用する方法の実際の例を次に示します。stdio_filebuf
stdiobuf
stdiobuf
FILE*
popen
#include <ext/stdio_filebuf.h>
#include <stdio.h>
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
int main() {
FILE* f = popen("ls", "r");
__gnu_cxx::stdio_filebuf<char> fdbuf(f, std::ios::in);
std::ifstream in;
in.std::ios::rdbuf(&fdbuf);
string s;
in >> s;
cout << s;
pclose(f);
return 0;
}