Capturing syscall stdout without writing to file in C/C++

做~自己de王妃 提交于 2019-12-17 21:16:23

问题


I want to read the std output of a system call into a C/C++ string. Can I do this without using a temp file?

Perl

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

C++

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

回答1:


Using C's popen (probably the simplest solution, even if it doesn't use C++'s iostream):

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);

Assuming your iostream has the non-standard xfstream::xfstream(int fd) constructor:

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

Using Boost.Iostreams, you don't have to depend upon non-standard extensions to iostream:

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

Unfortunately, Windows is horrible and _popen only works for console applications; for a graphical app:

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]);

(completely untested)




回答2:


This might help you redirect stdout from a system call.



来源:https://stackoverflow.com/questions/1103047/capturing-syscall-stdout-without-writing-to-file-in-c-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!