windows 批处理文件输入验证 - 确保用户输入一个整数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/684301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Batch File input validation - Make sure user entered an integer
提问by Ben Brandt
I'm experimenting with a Windows batch file to perform a simple operation which requires the user to enter a non-negative integer. I'm using simple batch-file techniques to get user input:
我正在试验一个 Windows 批处理文件来执行一个简单的操作,该操作需要用户输入一个非负整数。我正在使用简单的批处理文件技术来获取用户输入:
@ECHO OFF
SET /P UserInput=Please Enter a Number:
The user can enter any text they want here, so I would like to add some routine to make sure what the user entered was a valid number. That is... they entered at least one character, and every character is a number from 0 to 9. I'd like something I can feed the UserInput into. At the end of the routine would be like an if/then that would run different statements based on whether or not it was actually a valid number.
用户可以在此处输入他们想要的任何文本,因此我想添加一些例程以确保用户输入的是有效数字。也就是说……他们至少输入了一个字符,每个字符都是一个从 0 到 9 的数字。我想要一些可以输入 UserInput 的东西。在例程的末尾就像一个 if/then,它会根据它是否实际上是一个有效数字来运行不同的语句。
I've experimented with loops and substrings and such, but my knowledge and understanding is still slim... so any help would be appreciated.
我已经尝试过循环和子字符串等,但我的知识和理解仍然很少......所以任何帮助将不胜感激。
I could build an executable, and I know there are nicer ways to do things than batch files, but at least for this task I'm trying to keep it simple by using a batch file.
我可以构建一个可执行文件,而且我知道有比批处理文件更好的方法来做事,但至少对于这个任务,我试图通过使用批处理文件来保持它的简单。
采纳答案by Ben Brandt
Thanks all. I was trying to make it harder for myself looking at loops and string manipulation. I used your tips on math evaluation and comparison. Here's what I finally came up with as my concept script:
谢谢大家。我试图让自己更难查看循环和字符串操作。我使用了你的数学评估和比较技巧。这是我最终想出的作为我的概念脚本的内容:
: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
This method catches all numbers and can detect whether it's positive, negative, or zero. Any decimal or string will be detected as non-integers. The only edge case I've found is a string with spaces. For example, the text "Number 1" will cause the script to crash/close when the user input is evaluated as math. But in my situation, this is fine. I don't want my script to go on with invalid input.
此方法捕获所有数字,并可以检测它是正数、负数还是零。任何小数或字符串都将被检测为非整数。我发现的唯一边缘情况是带有空格的字符串。例如,当用户输入被评估为数学时,文本“数字 1”将导致脚本崩溃/关闭。但在我的情况下,这很好。我不希望我的脚本继续使用无效输入。
回答by Joey
You're probably not doing this in a DOS batch file. Or at least, support for set /p
is unheard of for me in DOS :-)
您可能不是在 DOS 批处理文件中执行此操作。或者至少,set /p
在 DOS 中对我的支持是闻所未闻的 :-)
You could use substrings. In fact I have written a parser for a specific regular language that way once, but it's cumbersome. The easiest way would probably be to assign the contents of %userinput%
to another variable, using set /a
. If the result comes out as 0
you need to check whether the input itself was 0
, otherwise you can conclude it was a non-number:
您可以使用子字符串。事实上,我曾经以这种方式为特定的常规语言编写了一个解析器,但它很麻烦。最简单的方法可能是将 的内容分配%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
)
However, this works only for numbers in the range of Int32
. If you just care for any number (possibly floating-point as well) then you need to resort to the loop-based approach of dissecting it.
但是,这仅适用于范围内的数字Int32
。如果您只关心任何数字(也可能是浮点数),那么您需要使用基于循环的方法来剖析它。
NOTE:Updated to solve the space issues. However, there is still a problem lurking: Entering 123/5
yields "number", since set /a
can evaluate this ...
注意:已更新以解决空间问题。然而,仍然有一个问题潜伏着:输入123/5
收益率“数字”,因为set /a
可以评估这个......
回答by Wouter van Nifterick
This is the same idea as that of Johannes.. SET /A sets a numeric value. If the input is not a number, it changes it to 0. That's what you can exploit here to do your check.
这与 Johannes 的想法相同。 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
As an alternative, you could always create a little javascript file and call it from your batchfile. With parseInt() you could force the input to be an integer, or you could roll your own function to test the input.
作为替代方案,您始终可以创建一个小 javascript 文件并从您的批处理文件中调用它。使用 parseInt() 您可以强制输入为整数,或者您可以滚动自己的函数来测试输入。
Writing the javascript is just as fast as the batchfile, but it's much more powerful. No IDE or compiler required; notepad will do. Runs on every windows box, just like your batchfiles. So why not make use of it?
编写 javascript 与编写批处理文件一样快,但功能更强大。无需 IDE 或编译器;记事本就行。运行在每个 Windows 机器上,就像你的批处理文件一样。那么为什么不利用它呢?
You can even mix batchfiles and javascript. Example:
您甚至可以混合使用批处理文件和 javascript。例子:
contents of sleep.js:
sleep.js 的内容:
var SleepSecs=WScript.Arguments.Item(0);
WScript.Sleep(SleepSecs*1000)
contents of sleep.cmd:
sleep.cmd 的内容:
cscript /nologo sleep.js %1
You can now call this from a batchfile to make your script sleep for 10 seconds. Something like that is difficult to do with just a plain batchfile.
您现在可以从批处理文件中调用它以使您的脚本休眠 10 秒。仅使用普通的批处理文件就很难做到这样的事情。
sleep 10
回答by Joey
You can also use a quite simple trick:
您还可以使用一个非常简单的技巧:
echo %userinput%|findstr /r /c:"^[0-9][0-9]*$" >nul
if errorlevel 1 (echo not a number) else (echo number)
This uses findstr
's regular expression matching capabilities. They aren't very impressive but useful at times.
这使用findstr
的正则表达式匹配功能。它们不是很令人印象深刻,但有时很有用。
回答by Mike D
As pointed out by ghostdog74, the answers posted by Joey Mar 26 '09 (score 10) and Wouter van Nifterick Mar 26 '09 (score 5) don't work.
正如 ghostdog74 所指出的,Joey 2009 年 3 月 26 日(得分 10)和 Wouter van Nifterick 2009 年 3 月 26 日(得分 5)发布的答案不起作用。
The answer posted by Joey Mar 25 '10 (score 2) does work, except that redirection symbols and '&' cause syntax errors.
Joey Mar 25 '10 (score 2) 发布的答案确实有效,只是重定向符号和“&”会导致语法错误。
I think the best and simplest solution is the one posted by Sager Oct 8 '14 (score 0). Unfortunately, it has a typo: ‘"%a"' should be ‘"%a%"'.
我认为最好和最简单的解决方案是 Sager 于 2014 年 10 月 8 日发布的解决方案(得分 0)。不幸的是,它有一个错字:'"%a"' 应该是 '"%a%"'。
Here's a batch file based on Sager's answer. Redirection symbols and '&' in the input don't cause problems. The only problems I could find were caused by strings containing double quotes.
这是基于 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)
回答by Flora
I know this is years old, but just to share my solution.
我知道这已经多年了,但只是为了分享我的解决方案。
set /p inp=Int Only :
:: Check for multiple zeros eg : 00000 ::
set ch2=%inp%-0
if %inp% EQU 0 goto :pass
if [%inp%]==[] echo Missing value && goto :eof
if %inp:~0,1%==- echo No negative integers! && goto :eof
set /a chk=%inp%-10>nul
if %chk%==-10 echo Integers only! && goto :eof
:pass
echo You shall pass
:eof
Tested and working on Windows 8.
在 Windows 8 上测试和工作。
回答by Flora
You might also like this one - it's short and easy. This one use the multiplication trick to set TestVal. Comparing TestVal against UserInput allows all numeric values to get through including zeroes, only non-numerics will trigger the else statement. You could aslo set ErrorLevel or other variables to indicate a failed entry
您可能也喜欢这个 - 它简短而简单。这个使用乘法技巧来设置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
回答by Flora
In addition to the remark about the error that occures when spaces are part of the users input. You can use errorlevel errorlevel=9165. It can be used for the spaces in a string or for the error handling of 'no' input.
除了关于当空格是用户输入的一部分时发生的错误的评论。您可以使用 errorlevel errorlevel=9165。它可用于字符串中的空格或“no”输入的错误处理。
Kind Regards,
亲切的问候,
Egbert
埃格伯特
回答by Nerun
: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
)
)
It works fine to me. If he chooses numbers less or greater, strings, floating number etc, he wil receive a message ("You need to choose a NUMBER: 1 OR 2.") and the INPUT will be asked again.
它对我来说很好用。如果他选择小于或大于的数字、字符串、浮点数等,他将收到一条消息(“您需要选择一个数字:1 或 2。”)并且将再次询问 INPUT。
回答by ghostdog74
you can reinvent the wheel and grow a few white hairs doing string validation in batch, or you can use vbscript
您可以重新发明轮子并在批处理字符串验证中长出几根白发,或者您可以使用 vbscript
strInput = WScript.Arguments.Item(0)
If IsNumeric(strInput) Then
WScript.Echo "1"
Else
WScript.Echo "0"
End If
save it as checkdigit.vbs and in your batch
将其另存为 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
)