Почему CMD говорит «было неожиданно в это время» и закрывается, когда я что-то вводю в приглашение? - PullRequest
0 голосов
/ 30 сентября 2018

Я недавно видел видео VSauce 2 об игре, которую вы всегда можете выиграть, и я создал программу, в которой игрок может играть в игру против компьютера.Проблема в том, что когда наступает очередь пользователя, когда вы вводите число (или что-то еще), программа закрывается.Я и друг, который также программы пытались это исправить, но ничего не получалось.Думаешь, ты сможешь помочь?

Вот кусок кода, который продолжает портиться:

:usr
cls
echo.
echo SUM: %tot%
echo.
echo LAST ENTRY:
echo COMPUTER: %com%
echo YOU: %usr%
echo.
echo.
set/p usr=ENTER A NUMBER BETWEEN 1 AND 10: 
if "%usr%" => "11" (
goto usr
)
if "%usr%" =< "0" (
    goto usr
)
set/a tot=%tot%+%usr%
if "%tot%" == "100" (
    goto win
)
if "%tot%" => "101" (
    goto lose
) else (
    goto com
)

Каждый GOTO идет куда-то еще, что существует

1 Ответ

0 голосов
/ 01 октября 2018

1.usr в качестве имени для метки и переменной

Использование usr в качестве метки и в качестве имени переменной среды не является хорошей идеей, поскольку затрудняет поиск метки или переменной usr.


2.Недопустимые аргументы => и <=

=> и <= не являются допустимыми операторами сравнения для команды IF .Откройте окно командной строки и запустите if /? для получения справки по этой команде, в которой перечислены также все поддерживаемые операторы.

Любая внутренняя команда cmd.exe может быть выполнена в окне командной строки с параметром /? для отображенияпомощь для этой команды.И большинство внешних команд, которые являются консольными приложениями в каталоге %SystemRoot%\System32, также помогают при запуске их с /? в качестве параметра.


3.Сравнение целых и строковых значений

Такие операторы, как GEQ (больше или равно), предназначены в основном для 32-разрядных целочисленных сравнений со знаком.Заключив два аргумента для сравнения в двойные кавычки, командный процессор Windows больше не может преобразовывать строки в двойных кавычках в целые числа, поэтому сравнение строк выполняется с помощью IF .

Строка "2" больше строки "11".Первый символ двух сравниваемых строк - " с десятичным значением кода 34, равным для обеих строк.Второй символ - 2 со значением десятичного кода 50 в левой строке, которое больше 1 со значением десятичного кода 49 в правой строке, поэтому строка "2" больше строки "11".

Подробнее о сравнении строк и целых чисел читайте в ответе Символ, эквивалентный NEQ, LSS, GTR и т. Д. В пакетных файлах Windows


4.Правильный синтаксис команды

Командная строка set/p usr=ENTER A NUMBER BETWEEN 1 AND 10: не подходит, потому что cmd.exe должен применить автокоррекцию к командной строке, прежде чем она может быть выполнена.

Лучше будет:

set /P "usr=ENTER A NUMBER BETWEEN 1 AND 10: "

Аргумент 0 - это команда set.

Пробел используется для отделения команды от ее первого аргумента, который является опцией /P.

Еще один пробел используется для разделения второго аргумента variable=prompt text, заключенного в двойные кавычки, так как он содержит один или несколько пробелов.Заключение строки аргумента в двойные кавычки не требуется здесь в этом особом случае, потому что команда SET имеет специальный синтаксический анализ строки аргумента, которого нет в других командах и приложениях, но тем не менее лучше заключить вторуюаргумент в двойных кавычках в этой форме, чтобы увидеть конечный пробел и никогда не удалять его автоматически, например, с помощью текстового редактора, который обрезает конечные пробелы при сохранении файла.

Также возможно будет usr="ENTER A NUMBER BETWEEN 1 AND 10: " из-за другого специального анализакоманды set при использовании с опцией /P.Но прежний синтаксис лучше, потому что он может использоваться при каждом использовании set, а не только при использовании для запроса у пользователя строки.

Подробнее читайте в ответе на Почему нетвывод строки с 'echo% var%' после использования 'set var = text' в командной строке?


5.set /P против choice

При использовании set /P, чтобы запросить у пользователя строку, пользователь может вообще ничего не вводить или вводить то, что запрашивается пользователем, или вводить что-то совершенно иное, что можетсделать много хлопот при дальнейшей обработке строки пользовательского ввода.

Подробнее см. Как остановить интерпретатор команд Windows при выходе из пакетного файла при неправильном вводе пользователем?

Код, подобный этому, понадобится для отказоустойчивого кода в этом случае:

@echo off

:GetValue
set "UserValue="
set /P "UserValue=Enter a number between 1 and 10: "

rem Has the user not entered any string?
if not defined UserValue goto GetValue

rem Remove all double quotes from entered string.
set "UserValue=%UserValue:"=%"

rem Is there no string left anymore?
if not defined UserValue goto GetValue

rem Does the string contain any other character than a digit?
for /F delims^=0123456789^ eol^= %%I in ("%UserValue%") do goto GetValue

rem Remove all leading zeros because of an integer with a leading 0
rem is interpreted on IF comparsion below as an octal number and 08
rem and 09 would be interpreted as 0 because of invalid octal numbers.
:RemoveLeadingZeros
if "%UserValue:~0,1%" == "0" (
    set "UserValue=%UserValue:~1%"
    if not defined UserValue goto GetValue
    goto RemoveLeadingZeros
)

rem More than two digits are not allowed for a number in range 1 to 10.
rem This check must be done because of the user could enter also the
rem string 12345678901234567890 which is greater maximum positive 32-bit
rem integer value 2147483647 supported on conversion from string to integer.
if not "%UserValue:~2,1%" == "" goto GetValue

rem A value greater 10 is not allowed as also value 0 detected already
rem on removing leading zeros because of TempValue not defined anymore.
if %UserValue% GTR 10 goto GetValue

echo You entered the value %UserValue%.
pause

Это большой код, чтобы убедиться, что пользователь действительно ввел строку, которая является числом в диапазоне 1в 10.

Гораздо лучший код будет использовать внешнюю команду CHOICE , что объясняется выводом справки при запуске choice /? в окне командной строки:

@echo off
%SystemRoot%\System32\choice.exe /C 1234567890 /N /M "Enter 1 to 0 (=10): "
set "UserValue=%ERRORLEVEL%"
echo You entered the value %UserValue%.
pause

Это намного проще, и пользователь даже не может совершить опечатку, потому что CHOICE исключает только 1 , 2 , ..., 0 и Ctrl + C для выхода из выполнения пакетного файла.

Также возможно будет:

%SystemRoot%\System32\choice.exe /C 0123456789 /N /M "Enter 0 to 9: "

Результат тот же, что и раньше, из-за 0 приводит к выходу CHOICE с кодом выхода 1 и 9 с кодом выхода 10.


6.echo. может не вывести пустую строку

Тема форума DosTips ECHO.СБОЙ дать текст или пустую строку - вместо этого используйте ECHO / , объясняет, когда echo. не может вывести пустую строку.Лучше использовать echo/ или echo( для вывода пустой строки.

В этом особом случае не соблюдается правило, записанное в пункте 4, из-за особого разбора строки аргумента команды ECHO игнорирование строки аргумента, состоящей только из пробелов / табуляций, и вывод состояния off или on при вызове ее без строки аргумента без пробелов.


7.Отказоустойчивый переписанный пакетный код

Здесь перезаписанный код пакета является отказоустойчивым.

@echo off
:UserInput
cls
echo/
echo SUM: %tot%
echo/
echo LAST ENTRY:
echo COMPUTER: %com%
echo YOU: %usr%
echo/
echo/
%SystemRoot%\System32\choice.exe /C 0123456789 /N /M "Enter 0 to 9: "
set /A tot+=%ERRORLEVEL%
if %tot% EQU 100 goto win
if %tot% GTR 100 goto lose
echo Reached code for "com".
goto :EOF

:win
echo Reached code for "win".
goto :EOF

:lose
echo Reached code for "lose".

Командная строка set /A tot+=%ERRORLEVEL% работает даже с переменной среды tot, не определенной.

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

  • choice /?
  • cls /?
  • echo /?
  • goto /?
  • if /?
  • set /?
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...