I am looking for a way to get the output of a command when it is run from within a C++ program. I have looked at using the system()
function, but that will just execute a command. Here's an example of what I'm looking for:
std::string result = system("./some_command");
I need to run an arbitrary command and get its output. I've looked at boost.org, but I have not found anything that will give me what I need.
system - run shell command int system (const char *command); The command is run noninteractively in a shell, output is to the terminal and your program waits for command completion.
C++ Output In C++, cout sends formatted output to standard output devices, such as the screen. We use the cout object along with the << operator for displaying output.
popen() gives you control over the process's input or output file streams. system() doesn't. If you don't need to access the process's I/O, you can use system() for simplicity. system() is in C89 and C99; popen() is Posix only (though the Windows API also has one).
#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(), buffer.size(), pipe.get()) != nullptr) { result += buffer.data(); } return result; }
Pre-C++11 version:
#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; }
Replace popen
and pclose
with _popen
and _pclose
for Windows.
Getting both stdout and stderr (and also writing to stdin, not shown here) is easy peasy with my pstreams header, which defines iostream classes that work like popen
:
#include <pstream.h> #include <string> #include <iostream> int main() { // run a process and create a streambuf that reads its stdout and stderr redi::ipstream proc("./some_command", redi::pstreams::pstdout | redi::pstreams::pstderr); std::string line; // read child's stdout while (std::getline(proc.out(), line)) std::cout << "stdout: " << line << '\n'; # if reading stdout stopped at EOF then reset the state: if (proc.eof() && proc.fail()) proc.clear(); // read child's stderr while (std::getline(proc.err(), line)) std::cout << "stderr: " << line << '\n'; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With