How to get the full stream output with pstreams?
http://pstreams.sourceforge.net/ pstreams is an apparently very simple library, re-implementing popen() for C++.
The library is very simple to install, consisting of only one single header file. You can download the header file here and add it to your application:
http://pstreams.cvs.sourceforge.net/viewvc/pstreams/pstreams/pstream.h?view=logI thought what I wanted was pretty straightforward: send a command to the system and get its output. The home page of pstreams (above) and the documentation offer the following example:
redi::ipstream in("ls ./*.h");
std::string str;
while (in >> str) {
std::cout << str << std::endl;
}
It seems to work well, but the code actually strips all spaces and carriage return from the output. Try this:
redi::ipstream in("ls -l"); /* The command has a slightly more complicated output. */
std::string str;
while (in >> str) {
std::cout << str
}
std::cout << std::endl;
and we get a looong concatenated string without any space.
I did my best to understand the documentation, and the closest I have come to a solution is this:
redi::ipstream in("ls -l");
std::string str;
while (!in.rdbuf()->exited()) {
in >> str;
开发者_运维问答}
std::cout << str << std::endl;
However, the output is completely truncated at the first space.
I am stymied.
Related questions:
popen equivalent in c++ How to execute a command and get output of command within C++ using POSIX?Note to moderators: a pstreams tag is required for this question and the other two above.
The streaming operator >> is designed to read a word at a time to a std::string, while skipping surrounding whitespace, just as you do when reading a number.
If you want to read an entire line of text at a time, use getline instead.
std::getline(in, str);
The question is nothing to do with my pstreams library really, it's about istream and you'd get exactly the same behaviour reading from an ifstream or other istream. But the easiest way to read all the child process' output is:
redi::ipstream in("ls -l");
std::stringstream ss;
ss << in.rdbuf();
std::string s = ss.str();
Solution, based on Bo Persson's hint:
#include <pstream.h>
#include <iostream>
#include <stdio.h>
int main() {
redi::ipstream in("ls -l");
std::string str;
std::string s;
while (std::getline(in, s)) {
str += s + '\n';
}
std::cout << str;
return 0;
}
[Edit:] And an even simpler solution, again based on Bo's comments:
include <pstream.h>
#include <iostream>
#include <stdio.h>
int main() {
redi::ipstream in("ls -l");
std::string str;
std::getline(in, str, '\0');
std::cout << str;
return 0;
}
精彩评论