我正在从批处理文件制作游戏,其中一个输入可以接受任何字符(〜!@#$%& *()`)和任何其他字符。有没有办法找到除数字以外的任何字符并使用GOTO命令?到目前为止,这是我的脚本:
set /p guess=
echo "%guess%"|findstr /L "[a-z][A-Z]~`!@#$%^&*()-_=+\^|^^;:"',<.>/?*"
if %errorlevel% == 0 goto Invalid_Number
if %guess% == %number% goto Correct
... everything else here ...
:Invalid_Number
echo Invalid Number. Input must be a number
pause
有没有办法让这项工作完成,只是拒绝访问,我在学校的计算机上测试它,但它可能无法正常工作。
答案 0 :(得分:3)
:ask
set /p "guess=?" || goto :ask
setlocal enabledelayedexpansion
for /f "delims=0123456789" %%a in ("!guess!") do set "guess="
endlocal & set "guess=%guess%"
if not defined guess (
echo invalid input
goto ask
)
echo valid input
测试背后的基本思想是在for /f
命令中使用数字作为分隔符,因此它们将从输入中删除。如果还有什么,则它不是数字,并且do
子句中的代码被执行。
启用/禁用delayedexpansion
以处理可在输入字段中键入的有问题的字符(特别是双引号)。
答案 1 :(得分:3)
将它放在脚本的底部:
:isInt <str>
for /f "delims=0123456789" %%a in ("%1") do exit /b 1
exit /b 0
然后调用它,执行
call :isInt %guess% && success || fail
这是一个更完整的例子:
@echo off
setlocal
set /a rand = %RANDOM% %% 10 + 1
:begin
set /P "guess=Guess a number between 1 and 10: "
call :isInt %guess% || goto invalid
if %guess% gtr 0 if %guess% lss 11 (
if %guess% equ %rand% (
echo Lucky guess!
exit /b
) else (
echo Oooh, so close. Try again.
goto begin
)
)
:invalid
echo Please enter a valid integer between 1 and 10.
goto begin
:isInt <str>
for /f "delims=0123456789" %%a in ("%1") do exit /b 1
exit /b 0
这与MC ND的解决方案基本相同,但不是使用for
语句来取消设置%guess%
,而是设置%errorlevel%
并停止在第一个非数字字符处循环。这使它无限小,效率更高。 :)
无论成功还是失败,我都希望使用conditional execution(&&
和||
内容。
答案 2 :(得分:3)
我可以建议你采用另一种更好的方法吗?而不是读取任何行,然后检查它是否包含数字,您的程序可能直接读取数字,因此不需要检查。这样做的方法是通过子例程模拟 SET /P
命令。这样,您可以为输入添加其他约束,例如读取最大位数。
@echo off
rem Read a number emulating SET /P command
rem Antonio Perez Ayala
setlocal
rem Define the following variable before call InputNumber subroutine
set "thisFile=%~F0"
call :InputNumber number="Enter a number of up to 5 digits: " 5
echo Number read: %number%
goto :EOF
:InputNumber var="prompt" [digits]
setlocal EnableDelayedExpansion
rem Initialize variables
if "%~3" equ "" (set numDigits=9) else set "numDigits=%3"
set "digits=0123456789"
for /F %%a in ('copy /Z "%thisFile%" NUL') do set "CR=%%a"
for /F %%a in ('echo prompt $H ^| cmd') do set "BS=%%a"
rem Show the prompt and start reading
set /P "=%~2" < NUL
set "input="
set i=0
:nextKey
set "key="
for /F "delims=" %%a in ('xcopy /W "%thisFile%" "%thisFile%" 2^>NUL') do if not defined key set "key=%%a"
rem If key is CR: terminate input
if "!key:~-1!" equ "!CR!" goto endRead
rem If key is BS: delete last char, if any
set "key=!key:~-1!"
if "!key!" equ "!BS!" (
if %i% gtr 0 (
set /P "=!BS! !BS!" < NUL
set "input=%input:~0,-1%"
set /A i-=1
)
goto nextKey
)
rem If key is not a digit: ignore it
if "!digits:%key%=!" equ "%digits%" goto nextKey
rem If can not accept more digits: ignore it
if %i% equ %numDigits% goto nextKey
rem Else: show and accept the digit
set /P "=%key%" < NUL
set "input=%input%%key%"
set /A i+=1
goto nextKey
:endRead
echo/
endlocal & set "%~1=%input%"
exit /B
您还可以在输入行中添加任何其他处理,例如显示星号而不是数字等。有关此主题的大型示例,请参阅this post