批处理文件在 if 语句中不断崩溃

Batch file keeps crashing at if statement

我正在制作一个简单的文字游戏。一切正常,直到到达 if 语句。我不知道我做错了什么。

@echo off

title Text Adventures

echo "What is your name?"

set /p name=

echo "That was a bad crash. Are you hurt, %name%?"

echo.

echo Y/N

set /p answer=

if %answer% equ y goto hurt

:hurt

echo.

echo "I see. That's a gnarly gash you've got there!"

这里我 re-written 这是一个使用函数的形式,并使用我提供给原始 post 的建议作为评论。

你知道我错误地假设你有使用标签的目的,但考虑到问题给出的方式,我认为你最好不要打扰它们。

这是一个 no-labels 版本:

@(SETLOCAL
  echo off
  title Text Adventures
)

CALL :Main

( ENDLOCAL
 ECHO. The Script Ended!
 PAUSE
 EXIT /B
)

:Main

  set /p "name=What is Your Name?"
  ECHO.
  CHOICE /M "That was a bad crash. Are you hurt, %name%?"
  
  If %ERRORLEVEL% equ 1 (
    echo.
    echo "I see. That's a gnarly gash you've got there!"
  ) ELSE (
    echo.
    echo "Oh Good!"
  )
  PAUSE
GOTO :EOF

这是标签版本。 (我删除了解释它是如何工作的以及为什么有代码的评论,所以它对你来说不会那么混乱。)

@(SETLOCAL
  echo off
  title Text Adventures
)

CALL :Main

( ENDLOCAL
 ECHO. The Script Ended!
 PAUSE
 EXIT /B
)

:Main

  set /p "name=What is Your Name?"
  ECHO.
  CHOICE /M "That was a bad crash. Are you hurt, %name%?"
  
  If %ERRORLEVEL% equ 1 (
    CALL :Hurt
  ) ELSE (
    CALL :NotHurt
  )
  PAUSE
GOTO :EOF

:Hurt
  echo.
  echo "I see. That's a gnarly gash you've got there!"
GOTO :EOF

:NotHurt
  echo.
  echo "Oh Good!"
GOTO :EOF

对于这种事情,我更喜欢使用选择,并且经常使用我的菜单宏 returns 所选选项作为变量 option

中的字符串

下面是一个 shell 脚本,演示了我经常使用的几个宏的用法。

@ECHO Off & Goto :main
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::                                           * Functions *                                      :::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:+------------------------------------------------------------------------------------------------+:
:ColorString
    (For %%C in (%~1)Do Set "rv=!rV!%/E%!#A!m%%~C%/E%0m"& Set /A "#A+=1"& IF "!#A!"=="37" (Set #A=31))
Exit /B 0
:+------------------------------------------------------------------------------------------------+:
:ColorMenu
rem  Set /A "RR=!random! %%195 + 60","GG=!random! %%195 + 60","BB=!random! %%195 + 60"
rem  Set "%~1=%/E%38;2;!RR!;!GG!;!BB!m!%~1!%/E%0m"
 Set "rV="& IF "!#A!"=="" (Set #A=32)
 (For %%C in ("!%~1!")Do Set "rv=!rV!%/E%!#A!m%%~C%/E%0m"& Set /A "#A+=1"& IF "!#A!"=="37" (Set #A=31)) & Set "%~1=!rV!"
Exit /B 0
:+------------------------------------------------------------------------------------------------+:
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:main                                  * Environment Definition *                                :::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Rem /* ensure correct environment for macro definitions */
 Endlocal & Setlocal DISABLEdelayedexpansion
:+------------------------------------------------------------------------------------------------+:
 For /F %%a in ('echo prompt $E ^| cmd')do (Set "/E=%%a[")
:+------------------------------------------------------------------------------------------------+:
Set "ChoList=0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
 Set "ColLETTERS=Set "Rv="& Set "#A=31" & (For %%A in ("$Str")Do Set "Word=%%~A" & For %%B In (0 1 2 3 4 5 6 7 8 9 a b c d e f g h i j k l m n o p q r s t u v w x y z . + - _ [ ] / \ ":")Do Set "Word=!Word:%%~B=%%~B !") & (Call :ColorString "!Word!" & Echo/!rV!)"
 Set "ColWORD/S=Set "#A=35"& Set "MSG=$Str" & For %%G in ("!MSG!")Do (For %%v in (%%~G)Do (Set "Rv="&Call :Colorstring "%%~v"& For %%x in (!Rv!)Do (Set "MSG=!MSG:%%~v=%/E%0m%%~x!")))&Echo/!MSG!"
 Set "List/D/V=Set "#$L=0"&Set "$$L="&For %%n in (1 2)Do if %%n==2 (For %%G in (!$L!)Do (Set "%%~G" > Nul &Set /A "#$L+=1"))Else Set $L="
 Set "Menu=For %%n in (1 2)Do if %%n==2 (!DIV!&Set "CH#=0"&(Set "CHCS="&For %%G in (!Options!)Do For %%i in (!CH#!)Do (Set "CHCS=!CHCS!!ChoList:~%%i,1!"&Set "Opt[!ChoList:~%%i,1!]=%%~G"& Set "Opt=%%~G" &Call :ColorMenu Opt &<Nul Set /P "=[!ChoList:~%%i,1!] !Opt!"&Set /A "CH#+=1"&Echo/))&!DIV!& For /F "Delims=" %%o in ('Choice /N /C:!CHCS!')Do (Set "OPTION=!Opt[%%o]!"))Else Set Options="
 Set "ColLINE=For %%n in (1 2)Do if %%n==2 (Echo/!$C!!$Str!%/E%0m)Else Set $Str="
:+------------------------------------------------------------------------------------------------+:
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::                                          * Script Body *                                     :::
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 Setlocal EnableDelayedExpansion
 for /F "usebackq tokens=2* delims=: " %%W in (`mode con ^| findstr Columns`) do Set "Console_Width=%%%W"
 Set "DIV="&For /L %%i in (2 1 %Console_Width%)Do Set "DIV=!DIV!-"
 Set "DIV=Echo/%/E%33m!DIV!%/E%0m"
 %List/D/V:$L=Colors%"Red=%/E%31m" "Yellow=%/E%33m" "Green=%/E%32m" "Blue=%/E%34m" "Purple=%/E%35m" "Cyan=%/E%36m" "White=%/E%37m" "Gray=%/E%90m" "Pink=%/E%91m" "Beige=%/E%93m" "Aqua=%/E%94m" "Magenta=%/E%95m" "Teal=%/E%96m" "Off=%/E%0m" "Black=%/E%30m"
 %List/D/V:$L=Actions%"Buy a house=Did you win the lotto" "Go for a drive=Start your engines" "Walk on the wild side=Get mauled by a lion" "Run a mile=Fit yet" "flee the realm=fall down a hole" "battle trolls=A losing battle" "puzzle a conundrum=Enigma's Stigmatised" "solve 42=life is meaningless"
 %ColLETTERS:$Str=Welcome.%
 %ColWORD/S:$Str=Hello there my friend^! How are you today.%
 %ColLINE:$C=Teal%What a world we live in^^!
 %Menu%"Buy a house" "Go for a drive" "Walk on the wild side" "Run a mile" "flee the realm" "battle trolls" "puzzle a conundrum" "solve 42"
  For %%G in ("!Option!")Do Echo/!%%~G!

菜单宏为其提供的每个参数构建一个选项列表,使用子字符串修改迭代 36 个字符的选项列表以构建最终选项 - 这意味着支持 36 个菜单选项。

更新

添加了一个额外的例子来展示一种使用选择来显示输出或采取行动而不需要条件测试的方法。使用 List/D/V 宏定义选项的值,可以直接展开选定的 OPTION。在这个例子中,它只是显示输出,但是可以分配包含简单命令的值,如 SetGotocall 以对所选菜单选项执行特定操作。

我忘了加暂停

@echo off

title Text Adventures

echo "What is your name?"

set /p name=

echo "That was a bad crash. Are you hurt, %name%?"

echo.

echo Y/N

set /p answer=

if %answer% equ y goto hurt

:hurt

echo.

echo "I see. That's a gnarly gash you've got there!"

pause