在 C++ Windows 控制台程序中使用 _execv() 函数时,我发现参数以空格分隔,每个子字符串在执行程序的参数列表中成为一个单独的参数。据推测,直到找到该程序后才会发生这种情况,因为即使程序路径参数包含空格也能找到它。
我写了两个程序来演示这个问题。 _spawnv() 也会发生同样的事情,如果我修改调用程序以使用 wchar_t 数组和 _wexecv()。
我在 Windows 10 上使用 Visual Studio 2017 将示例构建为 x86 或 x64 Windows 控制台应用程序项目。如何在使用其中一个函数时避免此问题?
// Calling program
#include "pch.h"
#include <iostream>
#include <process.h>
int main()
{
const char program[] = "C:\\Users\\dummy\\Documents\\Visual Studio 2017\\Projects\\execTest\\x64\\Debug\\testCalled.exe";
const char* arguments[] = { program, "Hello World!", nullptr }; // Note the multiple spaces
for (int a = 0; sizeof(arguments) / sizeof(*arguments) > a && arguments[a]; ++a) {
std::cerr << "Caller: " << a << " = " << arguments[a] << '\n';
}
std::wcerr << '\n';
auto rc = _execv(program, arguments);
perror("Exec fail ");
std::cerr << "return code " << rc <<'\n';
return rc;
}
// Called program
#include "pch.h"
#include <iostream>
int main( int argc, char** argv)
{
for (int a = 0; a < argc; ++a) {
std::cerr << "Called: " << a << " = " << argv[a] << '\n';
}
return 0;
}
Output:
Caller: 0 = C:\Users\dummy\Documents\Visual Studio 2017\Projects\execTest\x64\Debug\testCalled.exe
Caller: 1 = Hello World!
Called: 0 = C:\Users\dummy\Documents\Visual
Called: 1 = Studio
Called: 2 = 2017\Projects\execTest\x64\Debug\testCalled.exe
Called: 3 = Hello
Called: 4 = World!
最佳答案
在类 Unix 系统上,execve
是允许程序用另一个程序删除自身的系统调用,它接收单独参数,而exec
家族函数直接调用。
在 Windows 上,系统 API 定义了 CreateProcess
函数,该函数使用新程序的名称或路径(如 execve
所做的那样)和构建的单个命令行通过加入exec
的参数。
这意味着您必须将包含空格的参数括在显式双引号中。所以 Windows 的方式确实是:
const char* arguments[] = { program, "\"Hello World!\"", nullptr };
C 标准没有定义 execv
函数,它只在 Posix 和 Windows 中定义,尽管试图兼容不是 Posix 系统,所以警告是可以预料的...
关于c++ - 如何避免 Windows _exec* 和 _spawn* 函数在空格处拆分参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53218984/