我正在制作一个简单的批处理脚本,以便在批处理脚本中找出数组。
代码:
@echo off
setlocal EnableDelayedExpansion
set inputCount=0
set outputCount=0
:input
cls
set /p !number%inputCount%!=Input %inputCount%:
set /a inputCount=%inputCount%+1
if %inputCount% geq 3 goto output
goto input
:output
cls
echo !number%outputCount%!
set /a outputCount=%outputCount%+1
if %outputCount% geq 3 goto exit
goto output
:exit
pause
echo exit
在第4行,我将outputCount
设置为0
,然后我不会更改outputCount
直到第16行我向其添加1
。
我希望第16行的输出为outputCount=0+1=1
因此outputCount=1
。但是,当我使用echo on
运行代码以查看其正在执行的操作时,第16行的输出为outputCount=2+1=3
,将outputCount
设置为3
。
该计划似乎在第16行之前的某个时刻将outputCount
设置为2
而不是0
,但我看不出原因。
答案 0 :(得分:0)
首先,请查看Debugging a batch file,因为这是您编写批处理文件时需要学习的一课。
其次,阅读Why is no string output with 'echo %var%' after using 'set var = text' on command line?上的答案,该答案为在命令提示符窗口set /?
中运行的帮助输出提供了附加信息。
您似乎希望定义环境变量number0
,number1
和number2
,并在用户输入中为其分配字符串。
用于提示用户输入字符串的命令是
set /P "variable=prompt text: "
或
set /P variable="prompt text: "
通常建议使用第一个变体,尽管批处理文件编码新手通常不会使用,因为在将字符串赋值给环境变量时不知道如何使用双引号。第二个变体特定于set /P
也是可能的,并且在一些非常罕见的情况下确实需要,但在我看来应该避免使用,因为双引号在使用set
时没有{被解释为不同{1}}。
因此,让我们通过使用/P
四行注释来查看您的代码,在批处理文件的末尾添加一行rem
并在命令提示符窗口中运行该批处理文件:
set
输出结尾只是rem @echo off
setlocal EnableDelayedExpansion
set inputCount=0
set outputCount=0
:input
rem cls
set /p !number%inputCount%!=Input %inputCount%:
set /a inputCount=%inputCount%+1
if %inputCount% geq 3 goto output
goto input
:output
rem cls
echo !number%outputCount%!
set /a outputCount=%outputCount%+1
if %outputCount% geq 3 goto exit
goto output
:exit
rem pause
echo exit
set number
的一行。没有环境变量NUMBER_OF_PROCESSORS=2
,number0
,number1
也会由number2
输出。文件中的命令行set number
会在echo !number%outputCount%!
。
通过查看Windows命令解释器预处理每一行后真正执行的输出命令行,可以看到原因。
ECHO is OFF
用户输入的字符串,如果不是 RETURN 或 ENTER 被提示用户点击,应该分配给的环境变量名称存储在环境变量 set /p !number%inputCount%!=Input %inputCount%:
,number0
和number1
中。但是您的批处理文件永远不会定义环境变量number2
,number0
和number1
,因为您的意图是将输入字符串存储到名为number2
的变量中,{{ 1}}和number0
。所以这个命令行终于执行了:
number1
由于语法错误,这些命令行会导致批处理退出,但由于在控制台窗口中可以看到延迟扩展的使用,因此不会出现这种情况。
解决方案是批处理代码,如下所示:
number2
此批处理文件的输出在第一个提示符set /p =Input 0:
set /p =Input 1:
set /p =Input 2:
上输入,第二个提示输入,第三个提示符@echo off
setlocal EnableExtensions EnableDelayedExpansion
set "Index=0"
:Input
cls
set /A Index+=1
set /P "Number%Index%=Input %Index%: "
if not %Index% == 3 goto Input
cls
set "Index=0"
:Output
set /A Index+=1
if defined Number%Index% echo Number%Index%=!Number%Index%!
if not %Index% == 3 goto Output
endlocal
为:
Hello!
好的,我们还没有输入一个数字,因为我们可以自由地输入任何东西,从Bye!
输入错误的字符串。但批处理文件现在按预期工作。
进一步请注意Number1=Hello!
Number3=Bye!
之后的字符串是算术表达式,它被解析为与命令行上的任何其他字符串完全不同。例如,可以通过仅使用变量名称来引用环境变量的当前值,而不包含百分号或感叹号。这样就可以在 IF 或 FOR 命令块中使用算术表达式中的变量,而无需使用延迟扩展。在命令提示符窗口中运行Double quote " or | or < or > are bad inputs on user prompt
时的帮助输出解释了这种不同的解析行为以及算术表达式中可以像set /A
一样使用哪些运算符。
要了解使用的命令及其工作原理,请打开命令提示符窗口,执行以下命令,并完全阅读为每个命令显示的所有帮助页面。
set /?
+=
cls /?
echo /?
endlocal /?
goto /?
if /?
rem /?
更多提示:
请勿在批处理文件中使用set /?
,使用setlocal /?
或exit
,请参阅Where does GOTO :EOF return to?
在验证用户输入任何内容并且输入的字符串实际上是一个数字(十进制,八进制或十六进制)之后,请确保根据您和用户的期望处理该数字。我的意思在于:
exit /B
您期望得到什么结果,goto :EOF
或实际结果@echo off
set "Number=020"
set /A Number+=1
echo Result=%Number%
pause
?
以21
开头的数字字符串被解释为八进制数。以17
或0
开头的数字字符串被解释为十六进制数字。将0x
更改为0X
,结果为020
。为什么? 008
对八进制数无效,因此被1
替换为{1}}。