Основной вопрос:
Как изменить опубликованный пакетный скрипт combined.bat
, чтобы у меня был правильный вывод для OUTPUT_A
и OUTPUT_B
в одно и то же время выполнения? (Знание использования / области действия EnableDelayedExpansion требуется для обеспечения правильного решения)
Контекст:
Я объединил пакетные сценарии по двум следующим ссылкам:
https://stackoverflow.com/a/15535761/7889588
https://helloacm.com/the-chr-function-implementation-in-windows-pure-batch-script/
и создал следующий пакетный скрипт (позвольте мне обозначить это как combined.bat
) :
combined.bat
предназначен для преобразования ASCII-символов в десятичные ASCII-символы.
@echo off
@setlocal EnableDelayedExpansion
:: define characters from 32 to 126
set alphabet= !"#$%%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
set testVar=64_65_66_67_68_69_70_64
echo INPUT = %testVar%
echo.
set resultA=
call :CHR 64
set resultA=%resultA%%char%
call :CHR 65
set resultA=%resultA%%char%
call :CHR 66
set resultA=%resultA%%char%
call :CHR 67
set resultA=%resultA%%char%
call :CHR 68
set resultA=%resultA%%char%
call :CHR 69
set resultA=%resultA%%char%
call :CHR 70
set resultA=%resultA%%char%
call :CHR 64
set resultA=%resultA%%char%
echo OUTPUT_A = %resultA%
echo.
set char=randomValueJustToInitFill
call :split "%testVar%" "_" array
set resultB=
:: Loop through the resulting array
for /L %%I in (0, 1, %array.ubound%) do (
call :CHR !array[%%I]!
echo array[%%I] = !array[%%I]! = !char!
set resultB=!resultB!!char!
)
echo OUTPUT_B = !resultB!
echo.
goto :EOF
:CHR
:: valid range should be from 32 to 126 inclusive
if "%1"=="" goto :EOF
if %1 LSS 32 goto :EOF
if %1 GTR 126 goto :EOF
:: call function
call :ASCII %1 chr
:: print result, using ^ to escape special characters
:: such as <, > and |
REM echo.^%chr%
set char=^%chr%
:: end the script
goto :EOF
:: sub-routine
:ASCII
setlocal EnableDelayedExpansion
:: get the index
set /a var=%1-32
:: retrieve letter
set character=!alphabet:~%var%,1!
:: end the routine and return result as second parameter (out)
endlocal & set %2=^%character%
@EXIT /B 0
:: split subroutine
:split <string_to_split> <split_delimiter> <array_to_populate>
:: populates <array_to_populate>
:: creates arrayname.length (number of elements in array)
:: creates arrayname.ubound (upper index of array)
set "_data=%~1"
:: replace delimiter with " " and enclose in quotes
set _data="!_data:%~2=" "!"
:: remove empty "" (comment this out if you need to keep empty elements)
set "_data=%_data:""=%"
:: initialize array.length=0, array.ubound=-1
set /a "%~3.length=0, %~3.ubound=-1"
for %%I in (%_data%) do (
set "%~3[!%~3.length!]=%%~I"
set /a "%~3.length+=1, %~3.ubound+=1"
)
@EXIT /B 0
@endlocal
при запуске combined.bat
выдает следующее:
INPUT = 64_65_66_67_68_69_70_64
OUTPUT_A = Z[\]_`aZ
array[0] = 64 = Z
array[1] = 65 = [
array[2] = 66 = \
array[3] = 67 = ]
array[4] = 68 = _
array[5] = 69 = `
array[6] = 70 = a
array[7] = 64 = Z
OUTPUT_B = Z[\]_`aZ
OUTPUT_A
и OUTPUT_B
неверны. Это смещено на 26
. Я сделал обоснованное предположение, что это вызвано строкой 2
из combined.bat
, @setlocal EnableDelayedExpansion
.
Поэтому, когда я закомментирую строку 2
, изменив ее на REM @setlocal EnableDelayedExpansion
, отредактированный combined.bat
приведет к следующему:
INPUT = 64_65_66_67_68_69_70_64
OUTPUT_A = @ABCDEF@
array[0] = !array[0]! = !char!
array[1] = !array[1]! = !char!
OUTPUT_B = !resultB!
Как видите, OUTPUT_A
теперь правильно. Однако код пакета для OUTPUT_B
больше не работает должным образом. Я попытался немного поработать со сценарием (то есть поместить EnableDelayedExpansion
в разные места и т. Д.). Я все еще не могу заставить скрипт выдавать корректный вывод для OUTPUT_A
и OUTPUT_B
в одно и то же время выполнения.
При предоставлении решения, пожалуйста, уточните в отношении изменений скрипта, внесенных в combined.bat
.