C++ プログラム内からコマンドを実行するときに、その出力を取得する方法を探しています。system()
関数の使用を検討しましたが、それはコマンドを実行するだけです。私が探しているものの例を以下に示します。
std::string result = system("./some_command");
任意のコマンドを実行してその出力を取得する必要があります。ブーストしかし、必要なものを提供してくれるものは何も見つかりませんでした。
ベストアンサー1
#include <cstdio>
#include <iostream>
#include <memory>
#include <stdexcept>
#include <string>
#include <array>
std::string exec(const char* cmd) {
std::array<char, 128> buffer;
std::string result;
std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd, "r"), pclose);
if (!pipe) {
throw std::runtime_error("popen() failed!");
}
while (fgets(buffer.data(), static_cast<int>(buffer.size()), pipe.get()) != nullptr) {
result += buffer.data();
}
return result;
}
C++11 より前のバージョン:
#include <iostream>
#include <stdexcept>
#include <stdio.h>
#include <string>
std::string exec(const char* cmd) {
char buffer[128];
std::string result = "";
FILE* pipe = popen(cmd, "r");
if (!pipe) throw std::runtime_error("popen() failed!");
try {
while (fgets(buffer, sizeof buffer, pipe) != NULL) {
result += buffer;
}
} catch (...) {
pclose(pipe);
throw;
}
pclose(pipe);
return result;
}
popen
Windows の場合は、 とをおよびpclose
に置き換えます。_popen
_pclose
2024 編集:
std::unique_ptr
Ubuntu 24.04 などの新しいバージョンの gnu g++ では、削除子がからの戻り値を無視するため、上記のコードはエラーになりますpclose()
。
error: ignoring attributes on template argument ‘int (*)(FILE*)’ [-Werror=ignored-attributes]
ラップするためにコードを変更する必要がありましたpclose()
。ラッパーにラムダを使用しました。現在は次のようになっています:
std::unique_ptr<FILE, void(*)(FILE*)> pipe(popen(cmd.c_str(), "r"),
[](FILE * f) -> void
{
// wrapper to ignore the return value from pclose() is needed with newer versions of gnu g++
std::ignore = pclose(f);
});