【问题标题】:How to parse a command-line in the same way that VBScript does如何以与 VBScript 相同的方式解析命令行
【发布时间】:2019-01-19 11:58:09
【问题描述】:

我有一个简单的 C++ 程序,它列出了它得到的参数:

#include <iostream>

int main(int argc, char* argv[]) {
    for (int i = 1; i < argc; i++) {
        std::cout << argv[i] << std::endl;
    }
    return 0;
}

我只是在测试/解决这个问题,但最终目的是让它接受一些文件和目录的名称。

所以我将这些参数传递给它:

"\\server\directory\file.ext" "C:\trailing\backslash\" "file.txt"

但这是打印出来的:

\\server\directory\file.ext 
C:\trailing\backslash" file.txt

即第二个参数的尾部斜杠使它认为结束引号被转义了。

我在 VS2017 的属性页中设置参数,但在以下情况下得到相同的输出:

  • 我从 PowerShell 调用 exe。
  • 我允许外部工具通过我的 它已经构建的 exe 参数(这将是最终的结果 使用)。

如何让我的程序理解带有斜杠的引用路径是一个参数?

编辑 this article 的第 4 节准确地描述了我的问题。基本上,我想让我的 C++ 程序以与批处理文件或 VBScript 相同的方式解释参数。 我无法更改参数进入程序的方式

编辑我将简化问题:

上面的 C++ 程序的行为如下:

我希望它的行为如下:

我必须对程序或编译器做些什么才能做到这一点?

【问题讨论】:

  • 文章Everyone quotes command line arguments the wrong way 介绍了函数ArgvQuote(),您可以使用它来正确引用参数(无论它是否有尾部反斜杠)。这是程序的调用者必须尊重的事情。否则这是他们的程序中的一个错误!
  • 这两篇文章都是关于如何在您正在创建的命令行中正确引用和转义字符。我说的是当我的程序被赋予一个许多程序可以处理的非常标准的 Windows 样式引用参数时,argv 中的结果内容是垃圾(一个带有斜杠的路径,其周围有引号)
  • 存在由 Microsoft C 运行时和CommandLineToArgvV 定义的如何解析命令行参数的事实上的标准。这个事实上的标准需要双反斜杠,如果它后面跟着一个双引号。如果您正在谈论的程序可以处理未转义的反斜杠,则它们正在以非标准方式解析命令行(例如,通过调用 GetCommandLine() 并进行手动解析。
  • 查看开源项目的源代码(碰巧是 7-Zip)如果在 WIN32 上编译,我可以看到非标准解析正在进行。多么令人失望。 SplitCommandLine 从 main 调用...哦,好吧...github.com/kornelski/7z/blob/master/CPP/Common/…
  • 我冒昧地澄清了你的问题标题,以便从一开始就明确你想要什么。

标签: c++ windows winapi visual-c++


【解决方案1】:

您必须用另一个反斜杠保护尾随反斜杠,否则反斜杠将被视为以下双引号的转义字符。 请参阅 Raymond Chen 的 blog post,了解这种行为的基本原理。 以下是相关部分的引用:

  • 一串不带引号的反斜杠没有特殊含义。
  • 偶数个反斜杠后跟一个引号被视为一对受保护的反斜杠,后跟一个单词终止符。
  • 奇数个反斜杠后跟一个引号被视为一对受保护的反斜杠,后跟一个受保护的引号。

【讨论】:

    【解决方案2】:

    我尝试在下面的第二个参数上加上一个额外的斜线来编译它,并且能够产生所需的输出!

    "\\server\directory\file.ext" "C:\trailing\backslash\\" "file.txt"

    这是输出

    /home/a.out                                                                                                                          
    \server\directory\file.ext                                                                                                           
    C:\trailing\backslash\                                                                                                               
    file.txt 
    

    如果对你有帮助,请点赞我的帖子:D

    【讨论】:

    • 这里是 C++ 命令行参数的detailed explanation
    • 我同意,但如果我无法控制论点的构建方式怎么办?
    • @Jobbo "但是如果我无法控制参数的构建方式怎么办?" 您可以随时检查命令行参数是否有尾部反斜杠并考虑你的程序代码中的那种情况,就这么简单。
    • 你能详细说明我在 C++ 中是如何做到这一点的吗?
    • @πάνταῥεῖ 处理如此糟糕的输入并不容易。考虑"C:\path with spaces\"。 C 运行时会将其拆分为以下参数:C:\pathwithspaces"。如果可能的话,目前尚不清楚如何“修复”此类输入。通过正确引用来修复他们的程序是调用者的工作。
    【解决方案3】:

    如果你对命令行解析不满意,你可以自己做:

    只需使用GetCommandLine 并根据需要解析命令行。

    其他帖子已经描述了/应该如何处理命令行(参见blog post of Raymond Chen)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-03
      • 2016-07-26
      相关资源
      最近更新 更多