WedX - журнал о программировании и компьютерных науках

Как запросить целочисленный ввод от пользователя в пакетном файле

Я хочу создать пакетный файл в Windows, который позволит пользователю вводить только число от 1 до 31... Я мог бы использовать этот номер позже в пакетном файле... Это возможно?

я пробовал это

set /P "month=Enter the month of the year : "
findstr /i %month% %file% | sort /+24

Спасибо :)


  • Да, это возможно. Но что из того, что вы уже пробовали, не работает? 07.07.2016
  • Я пробовал с помощью команды SET/P, но пользователь может вводить буквы, а я этого не хочу... 07.07.2016
  • Вы должны обновить свой вопрос кодом, который вы пробовали до сих пор. Ввод с консоли по своей сути основан на строках, поэтому вы можете ожидать от пользователя чего угодно. Вам придется подтвердить это самостоятельно. 07.07.2016
  • Как я могу подтвердить это? Есть ли у вас предложения 07.07.2016
  • После того, как вы получили свою переменную, проверьте здесь числовую проверку: stackoverflow.com/questions/6120623/ 07.07.2016
  • Кстати, в году всего 12 месяцев :-p 07.07.2016

Ответы:


1

Итак, эти два варианта совершенно разные:

  • Позвольте пользователю вводить что угодно; затем проверьте, является ли ввод числом от 1 до 12, и повторите ввод, если это не так.
  • Позвольте пользователю просто ввести число от 1 до 12.

Пакетный файл ниже реализует второй метод:

@echo off
setlocal EnableDelayedExpansion

echo Precede numbers 1 and 2 by a zero
set /P "=Enter a month: " < NUL
choice /C 0123456789 > NUL
set /A "number=%errorlevel%-1"
if %number% gtr 1 echo %number% & goto continue
set /P "=%number%" < NUL
if %number% equ 0 (
   choice /C 12 > NUL
   set "digit2=!errorlevel!"
) else (
   choice /C 012 > NUL
   set /A "digit2=!errorlevel!-1"
)
echo %digit2%
set /A "number=number*10+digit2"
:continue

echo/
echo Number read: %number%
07.07.2016
  • Разрешение предшествующего 0 для чисел от 2 до 9 необязательно показалось бы мне более удобным, но в любом случае отличный подход! 08.07.2016

  • 2

    Очень простой, но эффективный метод, который я использую, когда мне нужен ненулевой числовой ввод, — это следующий код (обратите внимание, что впоследствии он проверяет ввод пользователя):

    :RETRY_RESET
    rem /* Since zero is considered as invalid, preset variable to `0` to
    rem    not keep the former value in case the user just presses ENTER;
    rem    you could also define a non-zero default value here optionally: */
    set /A NUMBER=0
    :RETRY_REUSE
    rem // Display prompt now:
    set /P NUMBER="Please enter a positive number: "
    rem /* Convert entry to a numeric value; everything up to the first
    rem    numeral is converted to a numeric value, except leading SPACEs
    rem    or TABs are ignored and signs `+` and `-` are recognised: */
    set /A NUMBER+=0
    rem /* Caution: numbers with leading `0` are converted to octal ones!
    rem    since `8` and `9` are not valid octal numerals, entries with
    rem    such figures and leading zeros are converted to `0`! */
    rem // Verify entry:
    if %NUMBER% EQU 0 goto :RETRY_RESET
    rem // Do something with `%NUMBER%` at this point...
    rem /* Afterwards you can jump to `:RETRY_RESET` to enter another number;
    rem    alternatively, jump to `:RETRY_REUSE` to maintain the former entry
    rem    in case the user just presses ENTER... */
    

    Это не приведет к ошибке для любой записи, о которой вы можете подумать, потому что переменная NUMBER, содержащая значение, никогда не расширяется до того, как она будет преобразована в истинное число с помощью set /A NUMBER+=0.

    Скрипт правильно распознает знаки + и -. Начальные пробелы игнорируются. Помимо всего этого, все до первой нечисловой цифры преобразуется в число; так, например, запись типа SPACE+15.75k преобразуется в 15, поскольку . не является числом.

    Недостатком этого подхода является то, что ведущие нули могут привести к неожиданным результатам, поскольку set /A интерпретирует числа, например, восьмеричные; так, например, 012 преобразуется в (десятичное) 10, а 08 и 09 преобразуются в 0, поскольку 8 и 9 не являются допустимыми восьмеричными цифрами.
    Хорошим моментом может быть тот факт, что шестнадцатеричные числа распознаются правильно в случае они имеют префикс 0x; например, 0x18 преобразуется в 24; 0xAS становится 10 (поскольку S не шестнадцатеричный).

    07.07.2016

    3

    Следующий сценарий представляет собой смесь как ограничивающих символов/ключей во время ввода, так и проверки символов/значений после ввода. Код довольно сложный, но очень гибкий и безопасный. Вот:

    @echo off
    setlocal EnableExtensions DisableDelayedExpansion
    
    rem // Define constants here (`findstr` reg. expr.):
    set "WHITE=[0-9]" & rem // (positive list, accepted characters)
    set "BLACK=[^`^]" & rem // (negative list, rejected characters)
    set "LENGTH=2"    & rem // (optional limit for length of entry)
    
    rem // resolve length limit:
    set /A LENGTH-=1
    if %LENGTH% LSS 0 set "LENGTH="
    
    rem // Retrieve back-space character:
    for /F %%C in ('echo prompt $H ^| cmd') do set "BS=%%C"
    
    :HOOK
    rem // Display prompt:
    echo(Please enter something:
    set "ENTRY="
    
    :LOOP
    rem // Use `xcopy /W` to capture a single key stroke:
    set "KEY="
    for /F "delims=" %%K in ('2^> nul xcopy /L /W "%~f0" "%~f0"') do (
        if not defined KEY set "KEY=%%K"
    )
    set "KEY=%KEY:~-1%"
    rem // Leave loop in case ENTER has been pressed:
    if not defined KEY goto :NEXT
    rem // Disallow `"` to avoid syntax errors (`if`, no del. exp.):
    set "KEY=%KEY:"=%" & rem "
    rem // Disallow `=` to avoid syntax errors (`set /P`):
    if "%KEY%"=="=" set "KEY="
    rem // Disallow `   ` (tabulator):
    if "%KEY%"=="   " set "KEY="
    rem // Optional additional filter (include):
    if defined WHITE (
        (echo("%KEY%" | > nul findstr /R /C:"%BS%" /C:"%WHITE%") || (
            set "KEY="
        )
    )
    rem // Optional additional filter (exclude):
    if defined BLACK (
        (echo("%KEY%" | > nul findstr /R /C:^"\"%BLACK%\"^") || (
            set "KEY="
        )
    )
    rem // In general, display string equals pressed key:
    set "DISPLAY=%KEY%"
    rem // Avoid space in display text (ignored by `set /P`):
    if "%KEY%"==" " set "DISPLAY=_%BS% "
    rem // Force to clear preceding character upon back-space:
    if "%KEY%"=="%BS%" (
        set "DISPLAY=%BS% %BS%"
        if defined ENTRY set "ENTRY=%ENTRY:~,-1%"
        set "KEY="
    )
    rem // Ignore any more character if length limit is reached:
    set "TEST=%ENTRY%"
    if defined LENGTH if defined ENTRY (
        call set "TEST=%%ENTRY:~,%LENGTH%%%"
    )
    if not "%TEST%"=="%ENTRY%" (
        set "KEY=" & set "DISPLAY="
    )
    set "ENTRY=%ENTRY%%KEY%"
    rem // Show display text:
    < nul set /P ="%DISPLAY%"
    goto :LOOP
    
    :NEXT
    echo(
    rem /* Verify the entry; for instance,
    rem    check numeric value after removal of leading zeros: */
    cmd /C exit %ENTRY%
    set /A ENTRY=%ErrorLevel%
    set /A ENTRY+=0 & rem // (conversion to true numeric value)
    if %ENTRY% LEQ  0 goto :HOOK
    if %ENTRY% GTR 12 goto :HOOK
    rem // Do something with the entry (display):
    echo(You entered this value:
    < nul set /P ="%ENTRY%"
    echo(
    
    endlocal
    exit /B
    

    Ядром скрипта является команда xcopy /L /W, которая выполняется одним нажатием клавиши (/W) и не копирует (/L). Его вывод захватывается циклом for /F для получения текущего ключа или символа. Для отображения используется < nul set /P, в приглашение которого ничего не отправляется, кроме отображаемого текста сообщения, который не завершается разрывом строки, в отличие от echo. Обратитесь также к комментариям (rem) в коде.

    Скрипт можно настроить в блоке Define constants here вверху:

    • переменная WHITE определяет положительный набор символов для команды findstr, один из которых должен равняться символу/ключу; установите пустую строку, чтобы отключить этот набор; для нашей ситуации подходит [0-9], так как он определяет прием только числовых значений;
    • переменная BLACK определяет отрицательный набор символов для команды findstr, один из которых символ/ключ не должен не совпадать; установите пустую строку, чтобы отключить этот список; поскольку WHITE уже определено, BLACK не требуется; первый символ в скобках [ ] должен быть символом вставки ^, чтобы данные символы действительно отбрасывались; если наборы в WHITE и BLACK перекрываются, последний имеет приоритет;
    • переменная LENGTH определяет наибольшую длину записи, поэтому, если задано заданное количество символов, больше не принимается; вы можете удалить последний символ с помощью клавиши ; поскольку нам нужно двузначное числовое значение, 2 является предпочтительным значением здесь;
    07.07.2016

    4
  • Разве это не должно быть от 1 до 12 в месяц? 07.07.2016
  • @ManoDestra, оператор говорит between 1-31 07.07.2016
  • Не знал, что в году 31 месяц. ОП должен ошибаться :-p Хорошее решение. 07.07.2016
  • @ThomasJomphe терпит неудачу, если пользователь вводит что-то вроде 2xy (после вашего редактирования - исходный код npocmaka покрыл это) 07.07.2016
  • Я боюсь, что это не удастся, если пользователь введет что-то вроде 08 или 09... 07.07.2016
  • @aschipfl - ааа. Хорошее замечание. Добавлена ​​строка, которая очищает начальные нули. 07.07.2016
  • Новые материалы

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..

    ИИ в аэрокосмической отрасли
    Каждый полет – это шаг вперед к великой мечте. Чтобы это происходило в их собственном темпе, необходима команда астронавтов для погони за космосом и команда технического обслуживания..


    Для любых предложений по сайту: [email protected]