For most of my life, I've been using cstdio
. Now I'm trying to shift over to iostream
.
Suppose I have a separate program called "foo.cpp" that looks like this:
int main(){ // foo.cpp
int x;
std::cin >> x;
std::cout << x + 5 << "\n";
}
In another program called "bar.cpp", I call the foo executable. In the past, if I wanted to redirect stdin and stdout to a file, I would use freopen
like so:
int main(){ // bar.cpp, redirecting stdin and stdout
freopen("foo.in", "r", stdin); // Suppose "foo.in" contains a single integer "42"
freopen("foo.out", "w", stdout);
system("foo.exe"); // "foo.out" will contain "47"
}
Now I'm trying to redirect std::cin
and std::cout
to stringstreams. Something like this:
int main(){ // bar.cpp, redirecting cin and cout
std::istringstream instr("62");
std::ostringstream outstr;
std::cin.rdbuf(instr.rdbuf());
std::cout.rdbuf(outstr.rdbuf());
system("foo.exe"); // outstr should contain "67"
}
But what I've learned is that std::cin
and std::cout
was not redirected when executing "foo.exe". The program now expected user input and will print to std::cout
. When execution of "foo.exe" was done, std::cin
and std::cout
within "bar.cpp" still remained redirected to instr
and outstr
respectively.
My question is, is there a way to do it with iostream
like I intended, or am I stuck with using freopen
?
Haven't seen a freopen
call in a while. This brings back some old memories.
Anyway, I think you should stick with freopen
. The documentation page of the function literally states that this is one of the main use cases:
This function is especially useful for redirecting predefined streams like stdin, stdout and stderr to specific files.
I don't think you can do the redirection with iostream
only, because the iostream
library doesn't have an equivalent for the freopen
function.
It is interesting though why this solution you tried doesn't work:
std::cin.rdbuf(instr.rdbuf());
std::cout.rdbuf(outstr.rdbuf());
Maybe with those two lines you just affect the rdbuf of std::cin
and std::cout
from the current process and the subprocess has another instance of std::cin
and std::cout
.
The information about files seems to be copied from the parent process to the subprocess when calling system
. That is why the changes you do in the main process on stdin and stdout with freopen
are also visible in the subprocess.
Regardless, you should not use system to run a subprogram from your main C++ program. As you are probably on Windows (guessing from foo.exe
), I would analyze this example from Microsoft. It explains how to create a subprocess and use pipes to redirect the input and output of the subprogram.
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