当两个不同的参数中有空格时,C++系统()不工作

C++ system() not working when there are spaces in two different parameters

本文关键字:空格 C++ 系统 工作 两个 参数      更新时间:2023-10-16

我正在尝试使用system()运行一个需要一些参数的.exe。

如果在.exe的路径中有一个空格,并且在传入参数的文件的路径中,我会得到以下错误:

The filename, directory name, or volume label syntax is incorrect.

这是产生错误的代码:

#include <stdlib.h>
#include <conio.h>
int main (){
    system(""C:\Users\Adam\Desktop\pdftotext" -layout "C:\Users\Adam\Desktop\week 4.pdf"");
    _getch();
}

如果"pdftotext"的路径不使用引号(我需要它们,因为有时目录会有空格),那么一切都很好。此外,如果我把"system()"中的内容放在一个字符串中并输出它,然后在实际的命令窗口中复制它,它就可以工作了。

我想也许我可以用这样的东西链接一些命令:

cd C:UsersAdamDesktop;
pdftotext -layout "week 4.pdf"

所以我已经在正确的目录中了,但我不知道如何在同一个system()函数中使用多个命令。

有人能告诉我为什么我的命令不起作用吗?或者我想的第二种方式是否有效?

编辑:看起来我需要一组额外的引号,因为system()将其参数传递给cmd/k,所以它需要在引号中。我在这里找到的:

C++:如何使我的程序打开带有可选参数的.exe

所以我会投票以重复的方式结束,因为问题非常接近,尽管我们没有收到相同的错误消息,谢谢!

system()cmd /C command的身份运行命令。这里引用了cmd文档:

If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line, where the following logic is
used to process quote (") characters:
    1.  If all of the following conditions are met, then quote characters
        on the command line are preserved:
        - no /S switch
        - exactly two quote characters
        - no special characters between the two quote characters,
          where special is one of: &<>()@^|
        - there are one or more whitespace characters between the
          two quote characters
        - the string between the two quote characters is the name
          of an executable file.
    2.  Otherwise, old behavior is to see if the first character is
        a quote character and if so, strip the leading character and
        remove the last quote character on the command line, preserving
        any text after the last quote character.

您似乎遇到了情况2,cmd认为整个字符串C:UsersAdamDesktoppdftotext" -layout "C:UsersAdamDesktopweek 4.pdf(即没有第一个和最后一个引号)就是可执行文件的名称。

因此,解决方案是用额外的引号包裹整个命令:

//system(""D:\test" nospaces "text with spaces"");//gives same error as you're getting
system("""D:\test" nospaces "text with spaces"""); //ok, works

这很奇怪。我认为添加/S也是一个好主意,只是为了确保它总是按照情况2:解析字符串

system("cmd /S /C ""D:\test" nospaces "text with spaces"""); //also works

我来到这里是为了寻找答案,这就是我想出的代码(我这么明确是为了下一个人维护我的代码):

std::stringstream ss;
std::string pathOfCommand;
std::string pathOfInputFile;
// some code to set values for paths
ss << """;                             // command opening quote
ss << """ << pathOfCommand   << "" "; // Quoted binary (could have spaces)
ss << """ << pathOfInputFile << """;  // Quoted input (could have spaces)
ss << """;                             // command closing quote
system( ss.str().c_str() );             // Execute the command

它解决了我所有的问题。

很好地学习了系统调用的内部原理。同样的问题可通过C++字符串、TCHAR等进行复制(当然)。SetCurrentDirectory()调用一直对我有帮助。我首先设置当前路径,然后执行。到目前为止,这对我很有效。欢迎任何意见。-Sreejith。D.Menon