我的.bat脚本中的 If 语句未按预期工作



应该发生的是你输入一个介于 1 和 1,048,567 之间的数字。该程序会检查您的输入是否实际上是 1 到 1,048,567 之间的数字。如果您的输入是有效的数字,那么它将继续进入下一段代码。如果输入无效,则它将显示一条消息,指出它无效,然后循环并再次要求您输入。 但是,当我运行它时,我输入了任何内容,即使我输入了 1 到 1,048,567 之间的数字,它也会显示无效输入。

法典:

:setup
@echo off
title Pokemon Shiny Sim
set delay = nul
set count = 0
set chance = 4096
:settings
:setChance
cls
echo Set shiny chance (1 in x). Range: (1-1,048,567)
echo Leave blank for 1 in 4096.
set /p chance = Input: 
set /a chance = %chance%+0
if %chance% GEQ 1 (
if %chance% LEQ 1048567 (
goto setDelay
)
)
echo Invalid Input.
pause
goto setChance
:setDelay
cls
echo Set delay between attempts in seconds. Range: (1-60).
echo Leave blank for no delay.
set /p delay = Input: 
set /a delay = %delay%+0
if %delay% == nul (
goto loopStart
)
if %delay% GEQ 1 (
if %delay% LEQ 60 (
cls
goto loopStart
)
)
echo Invalid Input.
pause
goto settings
:loopStart
set /a count = %count%+1
set /a rand = %random% %% %chance%+1
if %rand% == 1 (
echo Attempt: %count% | Shiny: Yes!
pause
)
else (
echo Attempt: %count% | Shiny: No
)
goto loopStart

我建议先阅读调试批处理文件,然后再阅读为什么
在命令行上使用"set var = text"后没有带有"echo %var%"的字符串输出的答案?

接下来看看下面你重写的代码:

:setup
@echo off
title Pokemon Shiny Sim
set "delay=0"
set "count=0"
set "chance=4096"
:settings
:setChance
cls
echo Set shiny chance (1 in x). Range: (1-1,048,567)
echo Leave blank for 1 in 4096.
set /P "chance=Input: "
set /A chance+=0
if %chance% GEQ 1 if %chance% LEQ 1048567 goto setDelay
echo Invalid input.
pause
goto setChance
:setDelay
cls
echo Set delay between attempts in seconds. Range: (1-60).
echo Leave blank for no delay.
set /P "delay=Input: "
set /A delay+=0
if %delay% == 0 goto loopStart
if %delay% GEQ 1 if %delay% LEQ 60 cls & goto loopStart
echo Invalid input.
pause
goto settings
:loopStart
set /A count+=1
set /A rand=%random% %% chance + 1
if %rand% == 1 (
echo Attempt: %count% ^| Shiny: Yes!
pause
) else (
echo Attempt: %count% ^| Shiny: No
)
goto loopStart

在此批处理代码中,将删除等号周围的所有空格。

命令行set "delay = nul"被修改为set "delay=0",因为在执行set /a delay = %delay%+0后,条件if %delay% == nul永远不会为真,从而导致执行set /a delay = nul + 0从而导致将值0分配给环境变量delaynul不存在的环境变量,该名称具有整数值。有效算术表达式的结果始终是作为字符串分配给环境变量的数字,而不是像nul这样的字符串。

set /a chance = %chance%+0被修改为set /A chance+=0set /a delay = %delay%+0被修改为set /A delay+=0,因为否则输入检查是不安全的,因为例如用户可以自由地输入变量chance|,从而导致执行命令行set /a chance = |+0从而导致批处理文件执行意外退出。

切勿在算术表达式中使用%variable%!variable!,因为通常不需要。

关于在命令提示符窗口中运行set /?的几个页面上的帮助输出在有关set /A用法的章节中解释了每个不能解释为数字或运算符的字符串会自动解释为环境变量的名称,其当前值应在计算表达式时转换为整数。如果环境变量根本没有定义,或者其值无法成功转换为 32 位有符号整数,则会在表达式中将其替换为整数值0

有一些例外,例如在算术表达式中使用随机数需要%random%!random!,或者当变量名称包含空格字符或将被解释为运算符的字符时。在这种情况下,Windows命令解释器必须将已经处于预处理状态或在命令执行之前立即执行的环境变量名称替换为环境变量的随机值set

set /a chance = %chance%+0还可能使此批处理文件的用户输入例如PROCESSOR_LEVELPROCESSOR_REVISION,并且此输入虽然根本不是数字,但将被处理为有效,因为这两个字符串是以数字作为值的环境变量的名称。 默认情况下,PROCESSOR_REVISION分配了一个十六进制数,但可以通过命令set将其全部或部分处理为数字。

另一个语法错误在块中

if %rand% == 1 (
echo Attempt: %count% | Shiny: Yes!
pause
)
else (
echo Attempt: %count% | Shiny: No
)

关键字else必须与IF条件的true分支的结束)在同一行上,该分支与)用空格字符分隔。

重定向运算符|必须使用插入符号进行转义,^才能解释为文本字符以输出到控制台窗口中。

注意:set /A chance+=0仍然可以输入例如170 percent170X,这导致chance具有值170,因此输入是有效的,尽管实际上输入的字符串不是数字。

要了解使用的命令及其工作原理,请打开命令提示符窗口,在那里执行以下命令,并仔细阅读为每个命令显示的所有帮助页面。

  • cls /?
  • echo /?
  • goto /?
  • if /?
  • pause /?
  • set /?
  • title /?

我还没有测试代码,但我在代码中发现了一些致命的问题。


错误设置变量

set /a count = %count% + 1

这将设置一个变量count(注意空格!删除空间!此外,这可以缩短为set /a count+=1.


ECHO特殊字符

|是为批量重定向保留的特殊字符之一。要正确echo它,请改用echo string ^| string


糟糕的IF陈述实践

if %rand% == 1 (

仅当%rand%是字母数字时才有效。如果%rand%是空格,则 cmd.exe 看到:

if == 1 (

这是不正确的。

要更正它,请执行

if "%rand%"=="1" (

或者,使用EQU进行数字比较,使用==进行字符串比较。

最新更新