我有一个奇怪的问题。下面的程序应该检查用户的输入并在屏幕上回显它,除非输入是我在“if”语句中定义的某种“命令”,如/ h或/ r或/ x。 IF语句将字符串视为单个项目,而不是几个单独的字符串。所以当我输入带分隔符的东西时 逗号(,) 分号(;) 等于(=) 空间 ( ) 标签 ( ) 引用(“) 它将搜索第二个项目,从而抛出错误并退出。 那是我的问题。如果你不能理解我,请测试这个程序。 在回显输入之前,我想以某种方式首先检查这些“命令”。 请赐教! :/ 感谢。
@echo off
:again
set /p input= ^>
if /i {%input%}=={/h} (
cls
echo /h
echo /r
echo /x
goto again
)
if /i {%input%}=={/r} (
cls
type blablafile.txt
goto again
)
if /i {%input%}=={/x} (
exit
)
echo %input%
goto again
答案 0 :(得分:4)
尝试将所有花括号更改为双引号。这修复了您在一些简单情况下提到的分隔符问题,例如输入字符串中的空格。例如,
if /i {%input%}=={/h}
可以更改为
if /i "%input%"=="/h"
请注意,这不会处理其他一些情况,例如输入字符串中的双引号。请参阅其他答案以获得解决方案。
答案 1 :(得分:3)
IF语句的一般形式为IF Value1 CompareOperator Value2 COMMAND
在实际执行IF之前,必须将该行解析为各种组件。有许多场景可能导致语法无效。
一些明显的字符是&
,|
,<
,>
等特殊字符:必须像^&
一样转义或引用{{1} }}
问题不明显是"&"
,<space>
,<tab>
,;
和,
等令牌分隔符。这些也必须被转义或引用。例如,使用=
作为用户输入的程序中的一行。扩展'%input%后,该行看起来
<space>
解析器在第一个未转义/未引用的标记分隔符处终止Value1,因此它认为Value1为if /i { }=={/h} (
并认为{
是CompareOperator的一部分。这会产生语法错误。
另一个问题是具有奇数引号的值,例如}
的用户输入示例。
"
报价是状态机。启用引用后,解析器会认为直到下一个引号的所有字符都是同一个字符串的一部分。所以解析器认为Value1是if /i {"}=={/h} (
,命令不完整 - 另一种语法错误。
部分解决方案
您可以执行类似
的操作{"}=={/h} (
它可以使用if /i "%input%"=="/h" ...
或;
或<space>
等输入。
但仍有许多输入会失败。例如:=
,"
。
完整解决方案
进行测试的唯一可靠方法是启用延迟展开并使用"&"
代替!input!
。这是有效的,因为解析器在延迟扩展发生之前检测到IF语句的各种组件。
%input%
解析器将Value1标识为if /i !input!==/h (
,然后在执行之前,将值扩展为用户输入。此时不再需要进行解析 - IF语句“知道”整个扩展值是要比较的值。
以下是使用延迟扩展修补程序的代码的完整工作版本:
!input!