Использование переменной в качестве индекса в пакетном массиве не удается - PullRequest
1 голос
/ 26 января 2020

Я хочу повторить, хотя пакетный массив:

SET DEF_APP[0].type=.html
SET DEF_APP[0].name=Firefox
SET DEF_APP[1].type=.htm
SET DEF_APP[1].name=Firefox
SET DEF_APP[2].type=.doc
SET DEF_APP[2].name=LibreOffice
SET DEF_APP[3].type=.docx
SET DEF_APP[3].name=LibreOffice

SET I=0
:APP_LOOP 
IF DEFINED DEF_APP[%I%].type ( 
   ECHO %DEF_APP[%I%].type% %I%
   ECHO %DEF_APP[%I%].name% %I%
   SET /A I=I+1
   GOTO :APP_LOOP 
)
ECHO "Length is" %I%
ECHO %DEF_APP[1].type% %I%
ECHO %DEF_APP[1].name% %I%

PAUSE
EXIT

Хотя% I% распечатывается как 1,2,3,4, кажется, что% I% нельзя использовать как индекс массива. Распечатка:

I 0
I 0
I 1
I 1
I 2
I 2
I 3
I 3
"Length is" 4
.htm 4
Firefox 4
Drücken Sie eine beliebige Taste . . .

Интересно, почему распечатка из массива всегда "Я" (без ошибок или что-то в этом роде)? В других примерах (как в Tutorialspoint в приведенном ниже примере) это должно работать. Они используют «CALL ECHO %% ...»

set Arr[0] = 1 
set Arr[1] = 2 
set Arr[2] = 3 
set Arr[3] = 4 
set "x = 0" 
:SymLoop 

if defined Arr[%x%] ( 
   call echo %%Arr[%x%]%% 
   set /a "x+=1"
   GOTO :SymLoop 
)
echo "The length of the array is" %x%

Когда я печатаю

ECHO %DEF_APP[1].name% %I%

(как и два последних эха), он выводит правильное значение " Firefox 1 ". Когда я печатаю do

SET I=1
ECHO %DEF_APP[%1%].name% %I%

, он печатает «I 1». Может ли быть так, что индекс% I% переходит в тип char вместо int? И почему печатается буква "я"?

Ответы [ 2 ]

1 голос
/ 26 января 2020

Позвольте мне поделиться своим способом сделать это, и я не являюсь автором этого метода. Это безопасный способ определить / использовать массивы в cmd / bat.

Я видел это на dostips.com / @ Aacini и после здесь / by @ user6811411 (удаленный пользователь), некоторое время a go. Исходный код макета выглядит примерно так:

Set "var=%var:,="&Set /a i+=1&Set "var[!i!]=%

Я предпочитаю заменить [] на один _

Кроме того, измените i + = на _i + = 1 + 0 , нет необходимости в предопределенной команде: set i=0

Но он всегда работает и требует enabledelayedexpansion переменных

@echo off && setlocal enabledelayedexpansion && title <nul && title ...\%~nx0

rem :: define a variable for array_layout ::
set "_def_app.type=.html,.htm,.doc,.docx"
set "_def_app_.name=firefox,libreoffice,libreoffice"

rem :: replace/incrementing delimiter by a set /a_i+1%% :: 
rem :: (miracle loop in set new variable _var_+i/index) ::
set "_def_app.type_0=%_def_app.type:,="&set/a _i+=1+0&set "_def_app.type_!_i!=%"
set "_def_app_.name_0=%_def_app_.name:,="&set/a _k+=1+0&set "_def_app_.name_!_k!=%"

rem :: use a for loop to echo/use the index array value i/I ::
echo/ && for /l %%i in (0 1 !_i!)do for /f tokens^=* %%I in ('echo/!_def_app.type_%%i!
')do echo/  %%I == ^^!_def_app.type_%%%i^^!

rem :: use a for loop to echo/use the indesx array value k/K ::
echo/ && for /l %%k in (0 1 !_k!)do for /f tokens^=* %%K in ('echo/!_def_app_.name_%%k!
')do echo/  %%K == ^^!_def_app_.name_%%%k^^!

rem :: get total index + 1 = positions
echo/ && for %%s in (i,k)do call set /a "_len_%%s=!_%%s!+1"

echo/  Index of [^^!_def_app.type^^!] is: 0-!_i!
echo/ Length of [^^!_def_app.type^^!] is: !_len_i!

echo/ && echo/  Index of [^^!_def_app_.name^^!] is: 0-!_k!
echo/ Length of [^^!_def_app_.name^^!] is: !_len_k!

%%_APPDIR__%timeout.exe -1 & endlocal & goto :EOF


  • Выходы:

  .html  == !_def_app.type_0!
  .htm  == !_def_app.type_1!
  .doc  == !_def_app.type_2!
  .docx  == !_def_app.type_3!

  firefox  == !_def_app_.name_0!
  libreoffice  == !_def_app_.name_1!
  libreoffice  == !_def_app_.name_2!

  Index of [!_def_app.type!] is: 0-3
 Length of [!_def_app.type!] is: 4

  Index of [!_def_app_.name!] is: 0-2
 Length of [!_def_app_.name!] is: 3

Press any key to continue...

  • Тот же код без комментариев ...
@echo off && setlocal enabledelayedexpansion && title <nul && title ...\%~nx0

set "_def_app.type=.html,.htm,.doc,.docx"
set "_def_app_.name=firefox,libreoffice,libreoffice"

set "_def_app.type_0=%_def_app.type:,="&set/a _i+=1+0&set "_def_app.type_!_i!=%"
set "_def_app_.name_0=%_def_app_.name:,="&set/a _k+=1+0&set "_def_app_.name_!_k!=%"

echo/ && for /l %%i in (0 1 !_i!)do for /f tokens^=* %%I in ('
echo/!_def_app.type_%%i!')do echo/  %%I == ^^!_def_app.type_%%%i^^!

echo/ && for /l %%k in (0 1 !_k!)do for /f tokens^=* %%K in ('
echo/!_def_app_.name_%%k!')do echo/  %%K == ^^!_def_app_.name_%%%k^^!

echo/ && for %%s in (i,k)do call set /a "_len_%%s=!_%%s!+1"

echo/  Index of [^^!_def_app.type^^!] is: 0-!_i!
echo/ Length of [^^!_def_app.type^^!] is: !_len_i!

echo/ && echo/  Index of [^^!_def_app_.name^^!] is: 0-!_k!
echo/ Length of [^^!_def_app_.name^^!] is: !_len_k!

timeout -1 & endlocal & goto :EOF

1 голос
/ 26 января 2020

Ключом к пониманию расширения или его неудачи является порядок трех разных фаз расширения.

Сначала происходит расширение процента.
Здесь раскрываются все переменные между знаками процента. Он не угадывает имена переменных. Это просто взять символы между знаками процента. Эта фаза расширяет переменные ПЕРЕД выполнением анализа, это особенно важно для блоков кода.

Затем для переменных (они также используют знаки процента) раскрываются. И последнее расширение - это отложенное расширение (должно быть включено)

Если перед строкой стоит команда CALL, начинается четвертый раунд расширения. Это процентное расширение.

К вашей проблеме с массивом:

SET I=1
ECHO %DEF_APP[%I%].name% %I%

Не может работать, поскольку расширение процента пытается расширить DEF_APP[ и ].name

Вы можете использовать

Echo !DEF_APP[%I%].name! %I%

Теперь% I% расширяется, а затем DEF_APP [1] .name

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...