Как получить полный поток вывода с помощью pstreams?

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;

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

Я в тупике.

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

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

3 ответа

Решение

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

Если вы хотите прочитать всю строку текста за раз, используйте вместо этого getline.

std::getline(in, str);

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

redi::ipstream in("ls -l");
std::stringstream ss;
ss << in.rdbuf();
std::string s = ss.str();

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

#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;
}
Другие вопросы по тегам