请帮助!我一直在互联网上寻找答案。
这是我的代码:
@echo off
title var test
:question
set a1=This
set a2=Is
set a3=a
set a4=Var
set a5=Test
choice /c 12345 /m "press a number"
if errorlevel=5 set num=5&goto answer
if errorlevel=4 set num=4&goto answer
if errorlevel=3 set num=3&goto answer
if errorlevel=2 set num=2&goto answer
if errorlevel=1 set num=1&goto answer
:answer
echo now change the answer.
set /p a%num%=
FOR /F "tokens=1-6" %%1 IN ("%a1% %a2% %a3% %a4% %a5% a%num%") DO echo %%1 %%2 %%4 %%5.&echo You typed=%%6
pause
goto question
如您所见,我让用户选择1到5之间的数字来更改特定单词。但是,当我尝试使用相同类型的代码来显示他键入的内容时,:(
答案 0 :(得分:2)
环境变量不应以数字开头,也应避免将数字用于循环变量。在命令提示符窗口call /?
中运行,输出是此命令的帮助,解释了如何使用%0
,%1
,%2
,...来引用批处理文件参数。解释了为什么以数字为首字符的环境变量和以数字为首的循环变量即使在
FOR 集中的a%num%
未引用环境变量a1
或a2
或a3
或a4
或{{ 1}}。它只是环境变量的名称。完全不需要a5
循环。
for
在输入到@echo off
title var test
:question
set "a1=This"
set "a2=Is"
set "a3=a"
set "a4=Var"
set "a5=Test"
%SystemRoot%\System32\choice.exe /C 12345E /N /M "Press a number in range 1-5 or E for exit: "
if errorlevel 6 goto :EOF
set "num=%ERRORLEVEL%"
set /P "a%num%=Now change the answer: "
echo %a1% %a2% %a3% %a4% %a5%.
call echo You typed: %%a%num%%%
pause
goto question
的数字call echo You typed: %%a%num%%%
上执行命令行之前,Windows命令处理器会解析命令行3
。由于命令call echo You typed: %a3%
导致第二次解析此命令行,导致将call
替换为环境变量%a3%
的值,因此a3
输出预期的字符串。
也可以将echo
替换为
call echo You typed: %%a%num%%%
使用延迟的环境变量扩展还会导致在执行命令setlocal EnableDelayedExpansion
echo You typed: !a%num%!
endlocal
之前对命令行进行双重解析。有关更多详细信息,请参见How does the Windows Command Interpreter (CMD.EXE) parse scripts?
还请阅读this answer,以获取有关命令 SETLOCAL 和 ENDLOCAL 的详细信息。
考虑到用户确实可以输入任何内容,上述批处理代码中的以下两行也不是很理想。
echo
例如,如果用户输入数字echo %a1% %a2% %a3% %a4% %a5%.
call echo You typed: %%a%num%%%
,然后在下一个提示符下输入:
1
然后,批处理文件执行的操作与设计的完全不同,并输出用户的帐户名。
安全将是批处理代码:
Your user name is:& setlocal EnableDelayedExpansion & echo !UserName!& endlocal & rem
现在,用户输入字符串无法再修改Windows命令处理器执行的命令行。
具有无效的 FOR 循环的解决方案是:
@echo off
title var test
setlocal EnableExtensions DisableDelayedExpansion
:question
set "a1=This"
set "a2=Is"
set "a3=a"
set "a4=Var"
set "a5=Test"
%SystemRoot%\System32\choice.exe /C 12345E /N /M "Press a number in range 1-5 or E for exit: "
if errorlevel 6 goto :EOF
set "num=%ERRORLEVEL%"
set /P "a%num%=Now change the answer: "
setlocal EnableDelayedExpansion
echo !a1! !a2! !a3! !a4! !a5!.
echo You typed: !a%num%!
endlocal
pause
goto question
如果使用use输入数字setlocal EnableDelayedExpansion
for /F tokens^=1-6^ eol^= %%A in ("!a1! !a2! !a3! !a4! !a5! !a%num%!") do echo %%A %%B %%C %%D %%E.&echo You typed: %%F
endlocal
,然后输入以分号开头的字符串,则 eol=
对于输出正确的所有内容也是必需的。在这种情况下, FOR 选项字符串不能用双引号引起来,例如1
,因为这样会将"tokens=1-6 eol="
定义为行尾字符,并且如果用户输入数字{ {1}},然后输入以"
开头的字符串。在执行命令1
之前,对整个"
命令行进行双重解析时,^
必须用cmd.exe
将等号和空格转义为文字字符。 / p>
注意: FOR 循环解决方案在用户为第一个变量值输入上面发布的特殊命令行字符串时无法正常工作。因此它也不是很安全。