Захват syscall stdout без записи в файл в C/C++

Я хочу прочитать стандартный вывод системного вызова в строку C/C++. Могу ли я сделать это без использования временного файла?

Перл

//without file io
$output = `echo hello`;

C++

//with file io
system ("echo hello > tmp");
std::fstream file ("tmp");
std::string s;
file >> s;

person Akusete    schedule 09.07.2009    source источник
comment
stackoverflow .com/questions/646868/   -  person alex vasi    schedule 09.07.2009
comment
Проблема здесь, конечно, в том, что системный вызов — это не то же самое, что вызов system().   -  person MSalters    schedule 09.07.2009
comment
@alex vasi: спасибо за ссылку, я сделал поиск, но не нашел эту страницу, прежде чем опубликовать вопрос.   -  person Akusete    schedule 10.07.2009


Ответы (2)


Использование popen C (вероятно, самое простое решение, даже если оно не использует iostream C++). ):

FILE *p = popen("echo hello", "r");
std::string s;
for (size_t count; (count = fread(buf, 1, sizeof(buf), p));)
    s += string(buf, buf + count);
pclose(p);

Предполагая, что ваш iostream имеет нестандартный конструктор xfstream::xfstream(int fd):

FILE *p = popen("echo hello", "r");
std::ifstream p2(fileno(p));
std::string s;
p2 >> s;
p2.close();
pclose(p);

Используя Boost.Iostreams, вам не нужно зависеть от нестандартные расширения для iostream:

boost::iostreams::file_descriptor_source p2(fileno(p));

К сожалению, Windows ужасна, и _popen работает только для консольных приложений; для графического приложения:

SECURITY_ATTRIBUTES sec;
sec.nLength = sizeof(sec);
sec.bInheritHandle = TRUE;
sec.lpSecurityDescriptor = NULL;
HANDLE *h[2];
CreatePipe(&h[0], &h[1], &sec, 0);
SetHandleInformation(h[0], HANDLE_FLAG_INHERIT, 0)
STARTUPINFO si;
memset((void *)&si, 0, sizeof(si));
si.hStdInput = INVALID_HANDLE_VALUE;
si.hStdOutput = h[1];
si.hStdError = INVALUD_HANDLE_VALUE;
si.dwFlags |= STARTF_USESTDHANDLES;
CreateProcess(NULL, "cmd /c \"echo hello\"", NULL, NULL, TRUE, 0, NULL, NULL, &si, NULL);
boost::iostreams::file_descriptor_source p(h[0]);

(полностью не проверено)

person ephemient    schedule 09.07.2009
comment
Подождите... вы вызываете p2.close(), а затем pclose() в том же потоке. Это означает, что вы пытаетесь закрыть его дважды. Мне кажется, что как только вы передадите его в ifstream, вы потеряете контроль над этим потоком и больше не сможете использовать p. - person Alexis Wilke; 23.01.2014

Это может помочь вам перенаправить стандартный вывод из системного вызова.

person Alan    schedule 09.07.2009