Первая ошибка уже есть в строке:
set place=%random% %% 5
Эта строка присваивает строку переменной среды place
, которая состоит из
- случайное десятичное число в диапазоне от 0 до 32767,
- пробел,
- знак процента,
- пробел и
- число 5.
В результате первая if
командная строка после обработки перед выполнением, например:
if x20934 % 5x==1 goto cave
Обработчик команд Windows завершает обработку пакетного файла с сообщением об ошибке :
% было неожиданным в то время.
Это довольно четкое сообщение об ошибке при отладке командного файла . Первым аргументом команды IF является x20934
, поэтому процессор команд Windows ожидает следующим либо оператор сравнения строк ==
, либо с включенными расширениями команд, как по умолчанию один из операторов EQU
, NEQ
, LSS
, LEQ
, GTR
, GEQ
, которые в основном предназначены для сравнения двух 32-битных целочисленных значений со знаком, но могут также использоваться для сравнения строк.
Пожалуйста, прочтите ответьте на Символ, эквивалентный NEQ, LSS, GTR и т. д. c. в Windows пакетных файлах для получения полной информации о том, как Windows командный процессор выполняет сравнение строк или целых чисел.
Таким образом, сначала необходимо исправить командную строку, которая должна оценивать a rithmeti c выражение и присвоить результат как строка переменной среды place
.
set /A place=%RANDOM% %% 5 + 1
Тогда можно будет использовать условия IF с помощью любого оператора ==
или EQU
для оценки результата.
Использование оператора сравнения строк ==
будет быстрее в этом случае, когда он на 100% уверен, что place
является строкой с первым символом 1
, 2
, 3
, 4
или 5
(со значением десятичного кода от 49 до 53), а второй символ является завершающим нулем (со значением десятичного кода 0). Таким образом, функция strcmp , используемая cmd.exe
, возвращает целочисленный результат уже после сравнения первого или второго символа (байта).
set /A place=%RANDOM% %% 5 + 1
if %place% == 1 goto cave
if %place% == 2 goto plains
if %place% == 3 goto swamp
if %place% == 4 goto volcano
if %place% == 5 goto fail
Также возможно использовать EQU
как оператор. Но в этом случае обе строки сначала преобразуются функцией strtol в 32-битные целые числа со знаком, которые затем сравниваются с помощью целочисленного сравнения. Это требует гораздо большего количества циклов процессора для выполнения sh сравнения.
set /A place=%RANDOM% %% 5 + 1
if %place% EQU 1 goto cave
if %place% EQU 2 goto plains
if %place% EQU 3 goto swamp
if %place% EQU 4 goto volcano
if %place% EQU 5 goto fail
Пользователь, запускающий командный файл, не заметит разницы. В настоящее время процессоры на ПК настолько быстры, что гораздо больше циклов ЦП, необходимых для выполнения двух strtol
по сравнению с выполнением одного strcmp
, составляет всего несколько микросекунд.
Эффективность выполнения командного файла может быть увеличен еще больше, если полностью исключить пять условий IF , потому что командный процессор Windows должен выполнить в худшем случае пять раз:
- Откройте командный файл.
- Установить позицию чтения файла в байтовое смещение конца последнего чтения.
- Прочитать байты из пакетного файла до следующего перевода строки.
- Предварительно обработать командную строку, чтобы узнать если необходимо прочитать больше строк.
- Запомнить текущую позицию байта в командном файле.
- Закройте командный файл.
- Полностью обработать командную строку и выполнить ее.
Условий IF можно избежать, используя соответствующие метки и используя только команду GOTO с меткой в зависимости от переменной среды place
: * 111 1 *
@echo off
set /A place=%RANDOM% %% 5
goto Place%place%
:Place0 - cave
echo You went for a crusade and ended up in a cave.& echo/& pause
rem More commands for cave.
goto :EOF
:Place1 - plains
echo You went for a crusade and found a plains biome.& echo/& pause
rem More commands for plains.
goto :EOF
:Place2 - swamp
echo You went for a crusade and ventured into a swamp.& echo/& pause
rem More commands for swamp.
goto :EOF
:Place3 - volcano
echo You went for a crusade and somehow ended up on a volcano.& echo/& pause
rem More commands for volcano.
goto :EOF
:Place4 - fail
echo Your boat sank and you survived. You lost 5 coins.& echo/& pause
Командный процессор Windows интерпретирует только строку после :
до первого символа-разделителя как метку. Таким образом, можно использовать метки, как показано выше, чтобы узнать, какая метка Place x
предназначена для какого места, поскольку строка после пробела игнорируется командным процессором Windows.
Выражение arithmeti c приводит к значению в диапазоне 0-4
, присвоенному как строка переменной среды place
, которая присоединяется к строке Place
в следующей командной строке к имени метки, которое будет обработано GOTO , чтобы продолжить обработку пакетного файла в строке под этой меткой.
Чтобы понять используемые команды и то, как они работают, откройте окно командной строки , выполните следующие команды и внимательно прочтите все страницы справки, отображаемые для каждой команды.
echo /?
goto /?
pause /?
rem /?
set /?
См. Также одну строку с несколькими командами для объяснения оператора &
.