Как получить полный поток вывода с помощью pstreams? - PullRequest
3 голосов
/ 15 марта 2011

http://pstreams.sourceforge.net/ pstreams - это, очевидно, очень простая библиотека, заново реализующая popen () для C ++.

Библиотека очень проста в установке, состоит только из одного заголовочного файла. Вы можете скачать заголовочный файл здесь и добавить его в свое приложение:
http://pstreams.cvs.sourceforge.net/viewvc/pstreams/pstreams/pstream.h?view=log

Я думал, что то, что я хотел, было довольно просто: отправить команду в систему и получить ее вывод. Домашняя страница pstreams (выше) и документация предлагают следующий пример:

redi::ipstream in("ls ./*.h");
std::string str;
while (in >> str) {
    std::cout << str << std::endl;
}

Кажется, это работает хорошо, но код фактически удаляет все пробелы и возврат каретки из вывода. Попробуйте это:

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;

и мы получаем длинную каскадную строку без пробелов.

Я приложил все усилия, чтобы понять документацию, и самое близкое, что я нашел к решению, это:

 redi::ipstream in("ls -l");
 std::string str;
 while (!in.rdbuf()->exited()) {
 in >> str;
 }
 std::cout << str << std::endl;

Однако вывод полностью усекается при первом пробеле.

Я в тупике.

Похожие вопросы:
эквивалент popen в c ++
Как выполнить команду и получить вывод команды в C ++, используя POSIX?

Примечание для модераторов: для этого вопроса требуется тег pstreams, а два других - выше.

Ответы [ 3 ]

7 голосов
/ 15 марта 2011

Оператор потоковой передачи >> предназначен для одновременного чтения слова в std :: string, при этом пропуская окружающий пробел, так же, как при чтении числа.всю строку текста за раз, используйте вместо этого getline.

std::getline(in, str);
3 голосов
/ 15 марта 2011

Вопрос не имеет ничего общего с моей библиотекой pstreams, это касается istream, и вы получите то же поведение при чтении из ifstream или другого istream. Но самый простой способ прочитать все выходные данные дочернего процесса:

redi::ipstream in("ls -l");
std::stringstream ss;
ss << in.rdbuf();
std::string s = ss.str();
0 голосов
/ 15 марта 2011

Решение, основанное на подсказке Бо Перссона:

#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:] И еще более простое решение, опять же на основе комментариев Бо:

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;
}
...