【发布时间】:2017-11-15 05:39:54
【问题描述】:
有一个程序可以解析 QB64 中的命令行。命令 $ 函数 返回命令行。我需要解析一个可能包含的长文件名 通过从引号内解析一个空格以与没有的文件名不同 空间。例如,“长文件名.ext”
问题是,当命令行没有引号时, command$ 返回 文件名,在引号中时,相同,例如“文件名”和“文件名”都返回文件名。但是,“”“文件名”“”返回 带引号的文件名...是否有另一种方法可以向 command$ 发送报价??
【问题讨论】:
有一个程序可以解析 QB64 中的命令行。命令 $ 函数 返回命令行。我需要解析一个可能包含的长文件名 通过从引号内解析一个空格以与没有的文件名不同 空间。例如,“长文件名.ext”
问题是,当命令行没有引号时, command$ 返回 文件名,在引号中时,相同,例如“文件名”和“文件名”都返回文件名。但是,“”“文件名”“”返回 带引号的文件名...是否有另一种方法可以向 command$ 发送报价??
【问题讨论】:
QB64 提供了COMMAND$ 和_COMMANDCOUNT 函数——主要类似于C++ 中的argv 和argc。 COMMAND$ 不带参数将返回一个包含所有命令行参数的字符串,但 QB64 还允许 COMMAND$(i) 以字符串形式检索索引 i 处的参数。来自 QB64 Wiki 上 _COMMANDCOUNT entry 的示例:
limit = _COMMANDCOUNT
FOR i = 1 TO limit
PRINT COMMAND$(i)
NEXT
您可以使用它们来处理 QB64 中的命令行参数。如果您想将包含引号的命令行参数传递给程序,您可能需要使用反斜杠转义要保留的引号。
不幸的是,反斜杠转义并不是万无一失的,特别是在cmd.exe 中可能会导致麻烦,主要是因为在文件路径中使用了反斜杠。将它与文件路径中的空格结合起来,你就有了一个噩梦般的命令解释器。从this answer 开始,您可以将带引号的字符串中的引号加倍以将正确的引号传递给程序:
> program.exe hello world
hello
world
> program.exe hello"" world
hello (+ empty quoted string)
world
> program.exe "hello"" world
hello"
world
> program.exe "hello""" world
hello" world
在 Wine 的 cmd.exe 中,"" 转义引号也关闭了引用的字符串,如上所示,因此需要立即连续的引号来继续将下一个间隔项与当前参数分组。由于我没有运行 Windows 机器,因此我不确定 Windows 的实现,但在我看来可能会发生相同的行为。
换句话说,你通过"""filename"""是因为:
" Open quoted string
"" Escaped double quote, closes quoted string
filename Concatenated at the end of the first quoted string
" Open quoted string, concatenated to filename
"" Escaped double quote, closes quoted string
编辑
您可以在带引号的字符串之外使用^",但这有其自身的问题,例如""^" 会导致",就像""" 一样。将""^" 传递给批处理文件需要额外的转义为""^^"。因此不建议使用^,尤其是当"" 和""" 也能正常工作时。有关^ 转义字符的信息,请参阅我上面链接的答案。
您还应该小心使用反斜杠和带引号的字符串。考虑如何将类 Unix 参数 'C:/Program Files/"file" name' 的正确 Windows 表示形式作为单个参数传递给程序:
> program.exe "C:\Program Files\\""file\"" name"
C:\Program Files\"file" name
cmd.exe解释:
" Open quoted string
C:\Program Files\\ Quoted string contents, including escaped \
"" Escaped double quote, closes quoted string
file\ Unquoted string contents, including C escape char
"" Open quoted string with escaped double quote
[ ]name Quoted string contents
" Close quoted string
这导致将"C:\Program Files\\"file\" name" 的命令行传递给程序,然后生成C:\Program Files\"file" name 的路径。当然,这样的路径在 Windows 中是不可能的(也许在 NTFS 文件系统上根本不可能?),但它说明了这一点:您需要考虑 cmd.exe 的引用规则和 C 运行时的引用规则和反斜杠转义。
【讨论】:
^",但在交互式会话中,您可能需要""(使用引号字符开始/结束带引号的字符串)或"""(用引号字符结束带引号的字符串并开始新的带引号的字符串)。我链接的答案有很多关于引号的各种转义规则的细节。我还编辑了我的答案,以帮助澄清有关反斜杠转义和双引号的一些事情。处理cmd.exe 时需要小心。如果可能,使用另一个命令解释器——Bash 是理想的,无论是 WSL bash、git-bash,甚至是 Cygwin 或 MSYS 中的 bash 版本。