Проверка ввода командного файла - убедитесь, что пользователь ввел целое число - PullRequest
12 голосов
/ 26 марта 2009

Я экспериментирую с командным файлом Windows, чтобы выполнить простую операцию, которая требует от пользователя ввода неотрицательного целого числа. Я использую простые методы пакетного файла для получения пользовательского ввода:

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

Пользователь может ввести любой текст, который он хочет, поэтому я хотел бы добавить некоторую подпрограмму, чтобы убедиться, что введенное пользователем действительное число. То есть ... они ввели по крайней мере один символ, и каждый символ представляет собой число от 0 до 9. Я хотел бы кое-что, что я мог бы передать UserInput. В конце подпрограммы это будет похоже на if / then, в котором будут выполняться другие операторы, основанные на том, действительно ли это было действительное число.

Я экспериментировал с циклами и подстроками и тому подобным, но мои знания и понимание все еще невелики ... поэтому любая помощь будет оценена.

Я мог бы создать исполняемый файл, и я знаю, что есть более приятные способы сделать что-либо, чем командные файлы, но по крайней мере для этой задачи я пытаюсь упростить его с помощью командного файла.

Ответы [ 14 ]

15 голосов
/ 26 марта 2009

Вы, вероятно, не делаете это в командном файле DOS. Или, по крайней мере, поддержка для set /p неслыханна для меня в DOS: -)

Вы можете использовать подстроки. На самом деле, я однажды написал парсер для определенного обычного языка, но это громоздко. Возможно, самым простым способом было бы присвоить содержимое %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 может оценить это ...

6 голосов
/ 26 марта 2009

Это та же идея, что и у Йоханнеса .. 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 или компилятор; Блокнот подойдет. Работает на каждом окне Windows, так же, как ваши пакетные файлы. Так почему бы не использовать это?

Вы даже можете смешивать пакетные файлы и JavaScript. Пример:

содержимое sleep.js:

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

содержимое sleep.cmd:

cscript /nologo sleep.js %1

Теперь вы можете вызывать это из пакетного файла, чтобы ваш скрипт спал в течение 10 секунд. Нечто подобное трудно сделать с простым пакетным файлом.

sleep 10
5 голосов
/ 26 марта 2009

Спасибо всем. Я пытался усложнить себе, глядя на петли и манипуляции со струнами. Я использовал ваши советы по оценке и сравнению математики. Вот что я наконец-то придумал в качестве своего концептуального скрипта:

: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

Этот метод перехватывает все числа и может определять, является ли оно положительным, отрицательным или нулевым. Любое десятичное число или строка будут обнаружены как нецелые. Единственный крайний случай, который я нашел, - это строка с пробелами. Например, текст «Номер 1» приведет к сбою / закрытию сценария, когда пользовательский ввод оценивается как математический. Но в моей ситуации это нормально. Я не хочу, чтобы мой сценарий продолжался с неверным вводом.

3 голосов
/ 25 марта 2010

Вы также можете использовать довольно простой трюк:

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

При этом используются возможности сопоставления регулярных выражений findstr. Они не очень впечатляют, но иногда полезны.

2 голосов
/ 06 июля 2016

Как указывает ghostdog74, ответы, опубликованные Джои Мар 26 '09 (оценка 10) и Вутер ван Нифтерик 26 марта 2009 (оценка 5), не работают.

Ответ от Joey Mar 25 '10 (оценка 2) работает, за исключением того, что символы перенаправления и '&' вызывают синтаксические ошибки.

Я думаю, что лучшее и простое решение - это сообщение, опубликованное Sager 8 октября '14 (оценка 0). К сожалению, в нем есть опечатка: «% a» должно быть «% a%».

Вот пакетный файл, основанный на ответе Сагера. Символы перенаправления и '&' на входе не вызывают проблем. Единственные проблемы, которые я мог найти, были вызваны строками, содержащими двойные кавычки.

@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)
1 голос
/ 01 мая 2015

Я знаю, что это лет, но просто чтобы поделиться своим решением.

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

Протестировано и работает на Windows 8.

1 голос
/ 04 мая 2009

В дополнение к замечанию об ошибке, которая возникает, когда пробелы являются частью ввода пользователя. Вы можете использовать errorlevel errorlevel = 9165. Он может использоваться для пробелов в строке или для обработки ошибок ввода «нет».

С уважением,

Эгберт

1 голос
/ 08 апреля 2009

Вам также может понравиться этот - он короткий и простой. Этот использует трюк умножения, чтобы установить 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
0 голосов
/ 08 октября 2014

Вы можете проверить любую переменную, если ее номер:

SET "var="&for /f "delims=0123456789" %i in ("%a") do set var=%i
if defined var (echo."NIC">nul) else (echo."number")
0 голосов
/ 17 июля 2014

Вы можете использовать подпрограмму ReadFormattedLine для всех видов форматированного ввода. Например, команда ниже читает число до 5 цифр:

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

Эта подпрограмма написана в чистом пакетном режиме, поэтому она не требует какой-либо дополнительной программы и позволяет выполнять несколько форматированных операций ввода, например, чтение паролей В предыдущем примере подпрограмма считывает число до 5 цифр. Вы можете скачать подпрограмму ReadFormattedLine из Читать строку с определенным форматом .

...