Как правильно выполнить числовое сравнение со строками в пакетном скрипте - PullRequest
0 голосов
/ 30 апреля 2019

Я не знаю, что не так со сценарием, но он всегда возвращает false, если входное значение больше 1, и вообще не выводится, если входное значение меньше 1.

Пример

@echo off

echo [1] Option 1
echo [2] Option 2
echo [3] Option 3
echo [4] Option 4
echo [5] Option 5
echo [6] Option 6
echo [7] Option 7
echo [8] Option 8
echo [9] Option 9
echo [10] Option 10

set /p option="Enter option (1-10): "

if "%option%" geq "1" if "%option%" leq "10" (
  echo %option% is greater than or qual to 1, and is less than or equal to 10
) else (
  echo Invalid option %option%
)

pause >nul

Вход

2

Выход

Invalid option 2

Ожидаемый результат

2 is greater than or qual to 1, and is less than or equal to 10

Ответы [ 3 ]

1 голос
/ 30 апреля 2019

Вы также можете сделать это немного более динамично, например:

@Echo Off
SetLocal EnableDelayedExpansion
For /F "Delims==" %%A In ('Set Option[ 2^>Nul')Do Set "%%A="
For /F "Tokens=1*Delims=:" %%A In ('FindStr "^::" "%~f0"^|FindStr /N "^"')Do Set "Option[%%A]=%%B"&Echo(%%A %%B
Set Option[>Nul 2>&1||Exit /B
Echo( Select an option from the list&Echo(
:Opt
::Option 1
::Option 2
::Option 3
::Option 4
::Option 5
::Option 6
::Option 7
::Option 8
::Option 9
::Option 10
Set /P "Opt="
Set Option[|Findstr /BL "Option[%Opt%]=">Nul||GoTo :Opt
Rem Your commands go below here.
Echo( You Selected "!Option[%Opt%]!"&Pause

Ваши параметры просто перечислены в вашем командном файле с добавлением неверно сформированной метки ::, что означаеткомандный файл не будет запускать их, но они могут быть прочитаны.Вход Set /P проверяется на соответствие тем, которые были динамически определены как переменные, и продолжается только после ввода правильного ввода.Строка, присвоенная выбранной переменной, может быть получена с использованием отложенного расширения как !Option[%Opt%]!, я добавил пример командной строки, чтобы показать вам ее использование.В заключение, параметры могут быть перемещены в любую позицию в скрипте.

1 голос
/ 30 апреля 2019

Использование choice.exe вместо set /p позволяет избежать проверки достоверности, поскольку ввод однозначен.
При использовании более 9 опций используйте также буквы, чтобы остаться при вводе одной клавишей.

:: Q:\Test\2019\04\30\SO_55920303.cmd
@echo off
:Loop
echo [1] Option 1
echo [2] Option 2
echo [3] Option 3
echo [4] Option 4
echo [5] Option 5
echo [6] Option 6
echo [7] Option 7
echo [8] Option 8
echo [9] Option 9
echo [A] Option 10
echo [Q] quit
choice /C 123456789AQ /M "Enter option"
if errorlevel 11 exit /B 0
echo You chose Option %ErrorLevel%
Timeout /t 3 >Nul
goto :loop
1 голос
/ 30 апреля 2019

Удалите кавычки для выполнения числовых сравнений:

set /p option="Enter option (1-10): "

if %option% geq 1 if %option% leq 10 (
    echo %option% is greater than or qual to 1, and is less than or equal to 10
) else (
    echo Invalid option %option%
)

С помощью кавычек вы вынуждены сравнивать строки, поскольку на самом деле они также являются частью сравниваемых значений.Если какой-либо из них не является числовым (что имеет место, если один из них или оба содержат кавычки), используется сравнение строк или алфавитов, где 2 больше 10, поскольку символ 2 получилкод выше 1.


Этот подход не работает, если входное значение %option% пусто;вы можете противодействовать, используя if defined:

:LOOP
rem // Reset variable, so it is empty if user just presses {Enter}:
set "option="
set /P option="Enter option (1-10): "
rem // Jump back to prompt if user did not enter anything:
if not defined option goto :LOOP
if %option% geq 1 if %option% leq 10 (
    echo %option% is greater than or qual to 1, and is less than or equal to 10
) else (
    echo Invalid option %option%
)

Или вы можете заставить значение быть числовым, пытаясь преобразовать с помощью set /A;это безопаснее, чем в предыдущем варианте, поскольку он работает даже в том случае, если запись пользователя содержит " и другие специальные символы:

set "option="
set /P option="Enter option (1-10): "
rem // Convert user entry to numeric value:
set /A "comp=option"
if %comp% geq 1 if %comp% leq 10 (
    echo %option% is greater than or qual to 1, and is less than or equal to 10
) else (
    echo Invalid option %option%
)

Конечно Расширение с отложенной переменной можно использовать какхорошо, чтобы избежать проблем с пустыми значениями или специальными символами:

set "option="
set /P option="Enter option (1-10): "
rem // Delayed expansion even allows to compare empty values and even to safely echo all possible strings:
setlocal EnableDelayedExpansion
if !option! geq 1 if !option! leq 10 (
    echo !option! is greater than or qual to 1, and is less than or equal to 10
) else (
    echo Invalid option !option!
)
endlocal

Давайте теперь сосредоточимся на самом условии if (с задержанным расширением здесь) и перепишем его немного:

if !option! geq 1 (
    if !option! leq 10 (
        echo !option! is greater than or qual to 1, and is less than or equal to 10
    ) else (
        echo Invalid option !option!
    )
)

Теперь вы можете четко видеть, что случай, когда !option! меньше 1, не обрабатывается;для этого вам понадобится еще одно else предложение:

if !option! geq 1 (
    if !option! leq 10 (
        echo !option! is greater than or qual to 1, and is less than or equal to 10
    ) else (
        echo Invalid option !option!
    )
) else (
    echo Invalid option !option!
)

Или вы просто используете goto, чтобы выполнить то же самое:

if !option! geq 1 if !option! leq 10 goto :NEXT
echo Invalid option !option!
goto :EOF
:NEXT
echo !option! is greater than or qual to 1, and is less than or equal to 10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...