我有这样的代码:如何将system()函数的输出重定向到变量?
system("echo %username%");
我想它的结果重定向到一个变量,说uname
。
我该怎么办呢?
我知道WinAPI,但我想这样做。
我有这样的代码:如何将system()函数的输出重定向到变量?
system("echo %username%");
我想它的结果重定向到一个变量,说uname
。
我该怎么办呢?
我知道WinAPI,但我想这样做。
快速,丑陋和肮脏的方法是将输出重定向到一个文件,然后读取该文件。
system("echo %username% > someFile.txt");
一个更精细的方式是使用CreateProcess
API使用以下命令行:cmd.exe /c echo %username%
该API允许您指定自定义的标准输入和标准输出。您可以为标准输出创建管道,如下所示:
HANDLE g_hChildStd_OUT_Wr = NULL;
SECURITY_ATTRIBUTES saAttr;
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
// Create a pipe for the child process's STDOUT.
//
if (!CreatePipe(&g_hChildStd_OUT_Rd, &g_hChildStd_OUT_Wr, &saAttr, 0)) return -1;
然后在CreateProcess API中使用此管道。事情是这样的:
TCHAR szCmdline[]=TEXT("cmd.exe /c echo %username%");
PROCESS_INFORMATION piProcInfo;
STARTUPINFO siStartInfo;
// Set up members of the PROCESS_INFORMATION structure.
//
memset(&piProcInfo, 0, sizeof(PROCESS_INFORMATION));
// Set up members of the STARTUPINFO structure.
// This structure specifies the STDIN and STDOUT handles for redirection.
//
memset(&siStartInfo, 0, sizeof(STARTUPINFO));
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdOutput = g_hChildStd_OUT_Wr;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
// Create the child process.
//
bSuccess = CreateProcess(NULL,
szCmdline, // command line
NULL, // process security attributes
NULL, // primary thread security attributes
TRUE, // handles are inherited
0, // creation flags
NULL, // use parent's environment
NULL, // use parent's current directory
&siStartInfo, // STARTUPINFO pointer
&piProcInfo); // receives PROCESS_INFORMATION
再从管道中读取像这样的东西:
DWORD dwRead, dwWritten;
CHAR chBuf[BUFSIZE];
BOOL bSuccess = FALSE;
HANDLE hParentStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
for (;;)
{
bSuccess = ReadFile(g_hChildStd_OUT_Rd, chBuf, BUFSIZE, &dwRead, NULL);
if(! bSuccess || dwRead == 0) break;
}
所以你需要知道什么时候该进程结束,做适当的清理将异步运行的进程。因此,为了完成这项工作,需要在这里学习一些细节。
一个完整的例子可以在这里找到: http://msdn.microsoft.com/en-us/library/windows/desktop/ms682499(v=vs.85).aspx
由于我的程序做了很多日志记录,我更喜欢肮脏的方式。谢谢。 – blah 2014-10-12 11:22:29
使用'system'将数据输出到文件中没有什么不好看的。可用命令以及命令字符串的解释方式取决于您正在运行的系统,但如果这对您的应用程序不是问题,那么'system'是一个非常好的解决方案。 – 2014-10-12 11:35:59
当我说丑陋和脏兮兮的时候有些夸张,但原因是这个方法有一些限制,因为不是所有的东西都可以通过在最后加入“> file.txt”很好地重定向,它涉及创建一个文件这也有一些后勤问题:命名文件,稍后删除文件等。 – 2014-10-12 11:52:06
如果目标仅仅是获得用户名,你有没有考虑getenv
; getenv("username")
将直接返回它。
否则,如果你有更多的,你想做的事,并希望在一个文件中的结果...你传递给system
的字符串传递给命令解释器,所以任何你可以做在命令行中cmd.exe
将在system
中工作:文件重定向,管道到另一个进程等。
您需要['pipe'](http://msdn.microsoft.com/en-us/library/windows/desktop/aa365152 (v = vs.85).aspx) – 2014-10-12 10:29:22
如果您需要的是用户名,请考虑使用操作系统本机接口。 'system'不仅不安全,而且还有_slow_(产生一个新的进程等)。如果您坚持重复使用另一个进程,请尝试使用['pipe'](http://linux.die.net/man/2/pipe)。无法检索用'system'调用的命令的输出。 – Kalrish 2014-10-12 10:31:16
好的,那么对于系统(“systeminfo”);输出大的地方,我如何将它重定向到文本文件? – blah 2014-10-12 10:34:24