【问题标题】:C++ parsing a command lineC++ 解析命令行
【发布时间】:2013-11-18 17:15:04
【问题描述】:

我正在尝试在 C++ 程序中运行两个命令行,但遇到一个奇怪的错误。我要运行的命令行是

vlc -vvv dshow:// :dshow-vdev='USB Video Device' :dshow-adev=""  :live-caching=50 :sout=#transcode{vcodec=WMV2,vb=800,acodec=wma2,ab=128,channels=2,samplerate=44100}:duplicate{dst=udp{dst=localhost:1234},dst=display} :sout-keep

vlc -vvv udp://@localhost:1234:network-caching=50

它们都在命令提示符下运行良好。但是当使用 C++ 系统 shell 调用来运行这些时,第一个失败,而第二个工作。我在 C++ 中运行这些的方式如下:

system( "\"G:/Program Files/VideoLAN/VLC/vlc\" -vvv dshow:// :dshow-vdev=\"USB Video Device\" :dshow-adev=\"none\"  :live-caching=50 :sout=#transcode{vcodec=WMV2,vb=800,acodec=wma2,ab=128,channels=2,samplerate=44100}:duplicate{dst=udp{dst=localhost:1234},dst=display}:sout-keep");

system( "\"G:/Program Files/VideoLAN/VLC/vlc\" -vvv udp://@localhost:1234:network-caching=50");

第一个命令抛出错误“G:/Program 不被识别为内部或外部命令、可运行程序或批处理文件。”,这很奇怪,因为两个命令处理文件路径的方式是相同的。请让我知道原因。 计算机在 Windows XP 上运行,我使用的是 Microsoft Visual Studio 2010。

【问题讨论】:

  • 在路径中的空格前添加 \。
  • 但是在第二个命令的空格之前也没有 \ ,但这有效。不管怎么说,多谢拉。我要试试这个!
  • 添加\也不起作用!
  • 尝试将整个系统 cmd 放入一个 char* 变量中。尝试先打印字符串,然后将该变量传递给系统。这样就可以判断cmd的解析是否正确。
  • 一般情况下,当您没有将路径用引号括起来以避免控制台解析“空格”的字符串分隔符时,就会出现此错误。但这在您显示的代码中似乎不是问题。

标签: c++ visual-c++ command-line command-prompt


【解决方案1】:

使用system() 运行命令有以下注意事项和您正在尝试的切换要求(来自 cmd 文档),因为它有效地运行cmd /C *mycommandhere*:

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.

如果您将命令重新格式化为:

    system("cmd /S /C \"\"c:\\testDir\"\"\\dir with spaces\"\"\\myexe.exe");

应该可以的:)(在以前的版本中我忘记了一些转义字符)。

还有一个related question here.

或者如果它仅适用于 Windows,您可以使用 ShellExecute 或 ShellExecuteEx 以及上述 msdn, here 上的一些文档

希望这会有所帮助,因为我刚刚失去了与我的家庭环境的连接,目前无法为我以前的修复获得一个固定版本,不过今晚会这样做。

【讨论】:

  • 这会给出“文件名、目录名或卷标语法不正确”错误!
  • 我会重新检查我输入的格式是否正确,可能遗漏了一些东西,抱歉。
【解决方案2】:

替换

system( "\"G:/Program Files/VideoLAN/VLC/vlc\" -vvv dshow:// :dshow-vdev=\"USB Video Device\" :dshow-adev=\"none\"  :live-caching=50 :sout=#transcode{vcodec=WMV2,vb=800,acodec=wma2,ab=128,channels=2,samplerate=44100}:duplicate{dst=udp{dst=localhost:1234},dst=display}:sout-keep");

system( "\"G:/Program Files/VideoLAN/VLC/vlc\" -vvv udp://@localhost:1234:network-caching=50");

与

system( "G:\\\"Program Files\"\\VideoLAN\\VLC\\vlc -vvv dshow:// :dshow-vdev=\"USB Video Device\" :dshow-adev=\"none\"  :live-caching=50 :sout=#transcode{vcodec=WMV2,vb=800,acodec=wma2,ab=128,channels=2,samplerate=44100}:duplicate{dst=udp{dst=localhost:1234},dst=display}:sout-keep");

system( "G:\\\"Program Files\"\\VideoLAN\\VLC\\vlc -vvv udp://@localhost:1234:network-caching=50");

【讨论】:

  • 也不起作用,因为文件路径被读取为 "G:/"Program Files"/VideoLAN/VLC/vlc"。我认为额外的引号引起了问题。给出错误“文件名、目录名或卷标语法不正确。”
  • 如果编辑后的解决方案适合您,请告诉我。
  • 不..它没有!同样的错误“文件名、目录名或卷标语法不正确。”再次
  • 你确定你提供的路径是正确的。可以在 cmd 提示符下从路径运行 vlc 吗?
  • 是的!我什至可以从 cmd 提示符运行整个流式传输命令。但我想使用来自 C++ 函数的相同命令启动流式传输。
猜你喜欢
  • 1970-01-01
  • 2010-11-27
  • 1970-01-01
  • 2016-03-24
  • 2013-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多