C++ で、コマンドの標準出力を取得する方法(CreateProcessなし)
はじめに
Windows でコマンドを実行する際、標準出力を取得する方法です。
コンソール画面が表示されても問題ない場合、
もしくは、CUIプログラムで使用できる方法です。
前提
system 関数だけでは、標準出力が簡単に取得できません。
Windows 環境では、APIの CreateProcess を使用する方法が良く使用されますが、popen を使用した方がシンプルに実装できます。
標準エラーの対応は、行っていませんが、
画面に表示したくない場合は、実行コマンド末尾に「 2>&1」を付けて標準出力にリダイレクトする等
適宜対応しましょう。
実装
#include <array> // array #include <cstdio> // _popen #include <iostream> // cout #include <memory> // shared_ptr #include <string> // string bool ExecCmd(const char* cmd, std::string& stdOut, int& exitCode) { std::shared_ptr<FILE> pipe(_popen(cmd, "r"), [&](FILE* p) {exitCode = _pclose(p); }); if (!pipe) { return false; } std::array<char, 256> buf; while (!feof(pipe.get())) { if (fgets(buf.data(), buf.size(), pipe.get()) != nullptr) { stdOut += buf.data(); } } return true; } int main(int argc, char** argv) { // 適当なコマンドを用意する const char* cmd = "dir"; std::string stdOut; int exitCode; if (ExecCmd(cmd, stdOut, exitCode)) { std::cout << stdOut << std::endl; } else { std::cout << "標準出力の取得に失敗しました。" << std::endl; } system("pause"); return 0; }
あとがき
Windows では、popen が使用できないと思い込んでいましたが、
_popen の名前で、使用できるので、実装して備忘録行き。