Capturing Stdout from a System() Command Optimally

How do I execute a command and get the output of the command within C++ using POSIX?

#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.

Extracting dos command output in C

There's nothing like that in standard C, but usually, for compatibility with POSIX, compilers implement popen (_popen in VC++), which starts a command (as it would do with system) and returns a FILE * to the stream you asked for (you can ask for stdout if you want to read the output or stdin if you want to give some input to the program).

Once you have the FILE *, you can read it with the usual fread/fscanf/..., like you would do on a regular file.

If you want to have both input and output redirection things start to get a bit more complicated, since Windows compilers usually do have something like POSIX pipe, but it isn't perfectly compatible (mostly because the Windows process creation model is different).

In this case (and in any case where you need more control on the started process than the plain popen gives you) I would simply go with the "real" way to perform IO redirection on Windows, i.e. with CreateProcess and the appropriate options; see e.g. here.

How to redirect output from reading a bash script in c++?

Use popen instead of system.

The function popen will give you a FILE * you can read from.

FILE *script = popen("myfile.sh", "r");
while (fgets(line, LENGTH, script)) {
/* ... */
}
pclose(script);

Hooking output from the console

Have you tried looking at the popen function? This older question has some discussion:

Capturing stdout from a system() command optimally

how to read from stdout in C

Create an executable using:

#include <stdio.h>

int main()
{
char line[BUFSIZ];
while ( fgets(line, BUFSIZ, stdin) != NULL )
{
// Do something with the line of text
}
}

Then you can pipe the output of any program to it, read the contents line by line, do something with each line of text.



Related Topics



Leave a reply



Submit