为什么IF语句会导致批处理文件退出?

问题描述 投票:-2回答:1

我曾尝试让代码随机选取一个1-5的数字,然后它会在游戏中随机选择一个区域。问题是,每当它执行时,它就一直退出。它也忽略了 x 之间 %place% 变量。

pause
set place=%random% %% 5
timeout 1
if x%place%x==1 goto cave
if x%place%x==2 goto plains
if x%place%x==3 goto swamp
if x%place%x==4 goto volcano
if x%place%x==5 goto fail
:cave
echo You went for a crusade and ended up in a cave.
pause
:plains
echo You went for a crusade and found a plains biome.
pause
:swamp
echo You went for a crusade and ventured into a swamp.
pause
:volcano
echo You went for a crusade and somehow ended up on a volcano.
pause
:fail
echo Your boat sank and you survived. You lost 5 coins.
pause
windows batch-file cmd
1个回答
1
投票

你的 set 声明需要 /a 开关,因为你正在尝试做数学。 另外,你需要在结果上加一个,因为现在你得到的是一个0-4范围内的随机数,而你的 if 语句的编号是1-5。 另外,我知道你说过要忽略X,但如果你想让你的程序正常工作,就必须去掉它们。 这是你的程序的编辑副本。

set /a place = %RANDOM% %% 5 + 1
timeout 1
if %place% equ 1 goto cave
if %place% equ 2 goto plains
if %place% equ 3 goto swamp
if %place% equ 4 goto volcano
if %place% equ 5 goto fail
:cave
echo You went for a crusade and ended up in a cave.
pause
:plains
echo You went for a crusade and found a plains biome.
pause
:swamp
echo You went for a crusade and ventured into a swamp.
pause
:volcano
echo You went for a crusade and somehow ended up on a volcano.
pause
:fail
echo Your boat sank and you survived. You lost 5 coins.
pause

0
投票

第一个错误已经出现在这一行

set place=%random% %% 5

这一行分配了一个... 绳子 到环境变量 place 其中包括

  • 一个随机的十进制数,范围为0至32767。
  • 一个空格字符。
  • 一个百分号。
  • 空格字
  • 数字5。

因此,第一个 if 命令行是在执行前处理后,例如。

if x20934 % 5x==1 goto cave

Windows命令处理器在退出批处理文件时,出现了错误信息:

%在这个时候出乎意料。

这是一个非常清晰的错误信息,在 调试批处理文件. 命令的第一个参数 IF 是 x20934 因此,Windows命令处理器接下来会期望使用字符串比较运算符 == 或启用了命令扩展,因为默认情况下,其中一个操作符是 EQU, NEQ, LSS, LEQ, GTR, GEQ 主要用于比较两个32位有符号的整数值,但也可用于字符串比较。

请阅读下面的答案 相当于Windows批处理文件中的NEQ、LSS、GTR等符号。 以了解Windows命令处理器如何进行字符串或整数比较的完整细节。

因此,首先需要纠正命令行,它应该评估一个新的字符串或整数。a算术表达式,并将结果赋值为 绳子 到环境变量 place.

set /A place=%RANDOM% %% 5 + 1

那么就可以使用 IF 的条件下,任何一个运算符 ==EQU 来评估结果。

字符串比较运算符的用法 == 会更快,在这种情况下,它是100%肯定的。place 是一个字符串,第一个字符是 1, 2, 3, 45 (十进制代码值为49~53),第二个字符是终止符null(十进制代码值为0)。所以函数 strcmp 所用 cmd.exe 返回第一个或第二个字符(字节)比较后的整数结果。

set /A place=%RANDOM% %% 5 + 1
if %place% == 1 goto cave
if %place% == 2 goto plains
if %place% == 3 goto swamp
if %place% == 4 goto volcano
if %place% == 5 goto fail

也可以使用 EQU 作为运算符。但在这种情况下,两个字符串都是先用函数 陌陌 到32位有符号的整数值,接下来使用整数比较进行比较。这需要更多的CPU周期来完成比较。

set /A place=%RANDOM% %% 5 + 1
if %place% EQU 1 goto cave
if %place% EQU 2 goto plains
if %place% EQU 3 goto swamp
if %place% EQU 4 goto volcano
if %place% EQU 5 goto fail

运行批处理文件的用户是看不出区别的。现在PC机的处理器速度非常快,执行两个 strtol 与单次执行相比 strcmp 仅为几微秒。

批量文件的执行效率可以进一步提高,避免了5个 IF 条件完全是因为Windows命令处理器要在最坏的情况下做五次。

  • 打开批处理文件
  • 将文件读取位置设为上次读取结束的字节偏移量。
  • 读取批处理文件中的字节,直至下一行的进位。
  • 对命令行进行预处理,找出是否需要读取更多行。
  • 记住当前批处理文件中的字节位置。
  • 关闭批处理文件。
  • 完全处理命令行并执行它。

读取 IF 的条件下,可以通过使用适当的标签来避免,只需使用命令即可。GOTO 根据环境变量的不同而贴上标签 place:

@echo off
set /A place=%RANDOM% %% 5
goto Place%place%

:Place0 - cave
echo You went for a crusade and ended up in a cave.& echo/& pause
rem More commands for cave.
goto :EOF

:Place1 - plains
echo You went for a crusade and found a plains biome.& echo/& pause
rem More commands for plains.
goto :EOF

:Place2 - swamp
echo You went for a crusade and ventured into a swamp.& echo/& pause
rem More commands for swamp.
goto :EOF

:Place3 - volcano
echo You went for a crusade and somehow ended up on a volcano.& echo/& pause
rem More commands for volcano.
goto :EOF

:Place4 - fail
echo Your boat sank and you survived. You lost 5 coins.& echo/& pause

Windows命令处理器只解释了在 : 到第一个分隔符作为标签。因此,可以使用如上图所示的标签来知道哪个是 场所x 标签是针对哪个地方的,因为字符串后的空格被Windows命令处理器忽略。

算术表达式的结果是一个在范围内的值。0-4 作为字符串分配给环境变量 place 与字符串 Place 在下一行命令中,将标签名称改为要由 GOTO 继续处理该标签下面一行的批处理文件。

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

  • echo /?
  • goto /?
  • pause /?
  • rem /?
  • set /?

也请参见 单行多命令 对于操作者的解释 &.

© www.soinside.com 2019 - 2024. All rights reserved.