批处理文件输入验证 - 确保用户输入了整数

时间:2009-03-26 02:15:15

标签: windows validation batch-file cmd scripting

我正在尝试使用Windows批处理文件来执行一个简单的操作,该操作要求用户输入一个非负整数。我正在使用简单的批处理文件技术来获取用户输入:

@ECHO OFF
SET /P UserInput=Please Enter a Number: 

用户可以在此处输入他们想要的任何文本,因此我想添加一些例程以确保用户输入的是有效数字。那就是......他们输入了至少一个字符,每个字符都是0到9之间的数字。我想要一些可以将UserInput输入的字符。例程结束时就像if / then那样根据它是否实际上是一个有效的数字来运行不同的语句。

我已经尝试过循环和子串等等,但我的知识和理解仍然很渺茫......所以任何帮助都会受到赞赏。

我可以构建一个可执行文件,我知道有比批处理文件更好的方法,但至少对于这个任务,我试图通过使用批处理文件来保持简单。

15 个答案:

答案 0 :(得分:15)

您可能没有在DOS批处理文件中执行此操作。或者至少,在DOS中我对set /p的支持是闻所未闻的: - )

您可以使用子字符串。事实上,我已经为特定的常规语言编写过一次解析器,但这很麻烦。最简单的方法可能是使用%userinput%set /a的内容分配给另一个变量。如果结果显示为0,则需要检查输入本身是否为0,否则您可以断定它是非数字:

@echo off
setlocal enableextensions enabledelayedexpansion
set /p UserInput=Enter a number: 
set /a Test=UserInput
if !Test! EQU 0 (
  if !UserInput! EQU 0 (
    echo Number
  ) else (
    echo Not a number
  )
) else (
  echo Number
)

但是,这仅适用于Int32范围内的数字。如果您只关心任何数字(也可能是浮点数),那么您需要采用基于循环的方法来解剖它。

注意:已更新以解决空间问题。但是,潜伏着仍然存在一个问题:输入123/5会产生“数字”,因为set /a可以对此进行评估...

答案 1 :(得分:6)

这与约翰内斯的想法相同。 SET / A设置数值。如果输入不是数字,则将其更改为0。 这就是你可以利用来做你的检查。

@ECHO OFF
SET /P UserInput=Please Enter a Number:
IF %UserInput% EQU 0 GOTO E_INVALIDINPUT

SET /A UserInputVal="%UserInput%"*1
IF %UserInputVal% GTR 0 ECHO UserInput "%UserInputVal%" is a number
IF %UserInputVal% EQU 0 ECHO UserInput "%UserInputVal%" is not a number
GOTO EOF

:E_INVALIDINPUT
ECHO Invalid user input

:EOF

作为替代方案,您始终可以创建一个小的javascript文件并从批处理文件中调用它。使用parseInt()可以强制输入为整数,或者您可以滚动自己的函数来测试输入。

编写javascript与批处理文件一样快,但功能更强大。无需IDE或编译器;记事本会做的。在每个窗口框上运行,就像批处理文件一样。那么为什么不利用它?

您甚至可以混合批量文件和JavaScript。例如:

sleep.js的内容:

var SleepSecs=WScript.Arguments.Item(0);
WScript.Sleep(SleepSecs*1000)

sleep.cmd的内容:

cscript /nologo sleep.js %1

现在可以从批处理文件中调用它来使脚本休眠10秒钟。仅仅使用普通的批处理文件就很难做到这一点。

sleep 10

答案 2 :(得分:5)

谢谢大家。我试图让自己更难以查看循环和字符串操作。我使用了你的数学评估和比较技巧。以下是我最终提出的概念脚本:

:Top
@ECHO OFF
ECHO.
ECHO ---------------------------------------
SET /P UserInput=Please Enter a Number: 
ECHO.
ECHO UserInput = %UserInput%
ECHO.
SET /A Evaluated=UserInput
ECHO Math-Evaluated UserInput = %Evaluated%
if %Evaluated% EQU %UserInput% (
    ECHO Integer
    IF %UserInput% GTR 0 ( ECHO Positive )
    IF %UserInput% LSS 0 ( ECHO Negative )
    IF %UserInput% EQU 0 ( ECHO Zero )
    REM - Other Comparison operators for numbers
    REM - LEQ - Less Than or Equal To
    REM - GEQ - Greater Than or Equal To
    REM - NEQ - Not Equal To
) ELSE (
    REM - Non-numbers and decimal numbers get kicked out here
    ECHO Non-Integer
)

GOTO Top

此方法捕获所有数字,并可以检测它是正数,负数还是零。任何小数或字符串都将被检测为非整数。我发现的唯一边缘情况是带空格的字符串。例如,文本“Number 1”将导致脚本在用户输入被评估为math时崩溃/关闭。但在我的情况下,这很好。我不希望我的脚本继续无效输入。

答案 3 :(得分:3)

您还可以使用一个非常简单的技巧:

echo %userinput%|findstr /r /c:"^[0-9][0-9]*$" >nul
if errorlevel 1 (echo not a number) else (echo number)

这使用findstr的正则表达式匹配功能。它们不是很令人印象深刻但有时很有用。

答案 4 :(得分:2)

正如ghostdog74指出的那样,2009年3月26日Joey发布的答案(得分10)和2009年3月26日的Wouter van Nifterick(得分5)不起作用。

Joey 2010年5月25日发布的答案(得分2)确实有效,除了重定向符号和'&'导致语法错误。

我认为最好最简单的解决方案是2014年10月8日Sager(得分0)发布的解决方案。不幸的是,它有一个错字:“%a”'应该是'“%a%”'。

这是基于Sager答案的批处理文件。重定向符号和'&'在输入中不会引起问题。我能找到的唯一问题是由包含双引号的字符串引起的。

@echo off & setlocal enableextensions & echo.
set /p input=Enter a string:
SET "x=" & for /f "delims=0123456789" %%i in ("%input%") do set x=%%i
if defined x (echo Non-numeral: "%x:~0,1%") else (echo No non-numerals)

答案 5 :(得分:1)

您可能也喜欢这个 - 它简短易行。这个使用乘法技巧来设置TestVal。将TestVal与UserInput进行比较允许所有数值通过包含零,只有非数字才会触发else语句。您可以设置ErrorLevel或其他变量来指示失败的条目

@ECHO OFF
SET TestVal=0

SET /P UserInput=Please Enter a Number:
SET /A TestVal="%UserInput%"*1

If %TestVal%==%UserInput% (
   ECHO You entered the number %TestVal%
   ) else ECHO UserInput "%UserInput%" is not a number

GOTO EOF

:EOF

答案 6 :(得分:1)

除了关于空格是用户输入的一部分时发生的错误的评论。您可以使用errorlevel errorlevel = 9165。它可以用于字符串中的空格或用于'no'输入的错误处理。

亲切的问候,

埃格伯

答案 7 :(得分:0)

:ASK
SET /P number= Choose a number [1 or 2]: 
IF %number% EQU 1 GOTO ONE
IF %number% NEQ 1 (
  IF %number% EQU 2 GOTO TWO
  IF %number% NEQ 2 (
    CLS
    ECHO You need to choose a NUMBER: 1 OR 2.
    ECHO.
    GOTO ASK
  )
)

对我来说很好。如果他选择的数字更少或更多,字符串,浮动数字等,他将收到一条消息(“你需要选择一个数字:1或2.”)并再次询问INPUT。

答案 8 :(得分:0)

你可以重新发明轮子并生长一些白头发批量进行字符串验证,或者你可以使用vbscript

strInput = WScript.Arguments.Item(0)
If IsNumeric(strInput) Then
    WScript.Echo "1"
Else
    WScript.Echo "0"
End If

将其保存为checkdigit.vbs并在批处理中

@echo off
for /F %%A in ('cscript //nologo checkdigit.vbs 100') do (
        echo %%A
        rem use if to check whether its 1 or 0 and carry on from here
)

答案 9 :(得分:0)

@echo off setlocal enableextensions enabledelayedexpansion set / p UserInput =输入一个数字: set / a Test = UserInput 如果!测试! EQU 0(   if!UserInput! EQU 0(     回声数   )其他(     echo不是一个数字   ) )其他(   回声数 )

yeaph everthing很棒 但你忘记了一件小事 0也是一个数字 ;(

答案 10 :(得分:0)

这更像是一种用户友好的方式。

if %userinput%==0 (
cls
goto (put place here)
)
if %userinput%==1 (
cls
goto (put place here)
)
if %userinput%==2 (
cls
goto (put place here)
)
if %userinput%==3 (
cls
goto (put place here)
)
if %userinput%==4 (
cls
goto (put place here)
)
if %userinput%==5 (
cls
goto (put place here)
)if %userinput%==6 (
cls
goto (put place here)
)if %userinput%==7 (
cls
goto (put place here)
)
if %userinput%==8 (
cls
goto (put place here)
)
if %userinput%==9 (
cls
goto (put place here)
)

这可用于任何类型的用户输入。

答案 11 :(得分:0)

您可以对所有类型的格式化输入使用ReadFormattedLine子例程。例如,下面的命令读取的数字最多为5位数:

call :ReadFormattedLine UserInput="#####" /M "Please Enter a Number: "

这个子程序是用纯批处理编写的,所以它不需要任何额外的程序,它允许几个格式化的输入操作,如读取密码。在前面的示例中,子例程读取的数字最多为5位。您可以从Read a line with specific format下载ReadFormattedLine子例程。

答案 12 :(得分:0)

您可以验证任何变量的编号:

SET "var="&for /f "delims=0123456789" %i in ("%a") do set var=%i
if defined var (echo."NIC">nul) else (echo."number")

答案 13 :(得分:0)

如果您想要某种循环并为该特定问题设置默认值,那么这是我执行此操作的方法。

其中的代码说明。

@echo off
setlocal EnableDelayedExpansion
set "ans1_Def=2"

:Q1
set /p "ans1=Opt 1 of 1 [Value 1-5 / Default !ans1_Def!]: "

:: If not defined section. This will use the default once the ENTER key has been
:: pressed and then go to :Q2.
if not defined ans1 (
  echo/ & echo ENTER hit and the default used. Default is still: !ans1_Def! & echo/
  set "ans1=!ans1_Def!" && goto :Q2 )

:: This section will check the validity of the answer. The "^[1-5]$" will work
:: for only numbers between one and five in this example but this can be changed
:: to pretty much suit the majority of cases. This section will also undefine
:: the ans1 variable again so that hitting the ENTER key at the question
:: will work.
echo %ans1%|findstr /r /c:"^[1-5]$" >nul
if errorlevel 1 (
  echo/ & echo At errorlevel 1. Wrong format used. Default is still: !ans1_Def! & echo/
  set "ans1=" && goto Q1
  ) else ( echo Correct format has been used. %ans1% is the one. && goto :Q2 )

:Q2
echo/
echo -----------------------------
echo/
echo Now at the next question
echo !ans1!
echo/
pause
exit

答案 14 :(得分:0)

尝试一下:

set /p numeric=enter a number

( 
  (if errorlevel %numeric% break ) 2>nul
)&&(
  echo %numeric% is numeric
)||(
  echo %numeric% is NOT numeric
)