3

I have an array in a batch file where I would like to get in each iteration the i element and i+1 (called in my batch serialNumberSection), starting from the second position of the input. So far, I have been able to get the i elements but I cannot do the same with the i+1 and I don't understand why.

What am I doing wrong?

input array = [0x33333 0xAA 0x33323130 0xBB 0x37363534 0xCC
0x42413938 0xDD 0x46454443]

My code

set argCount=0
for %%x in (%*) do (
    set /A argCount+=1
    set "argVec[!argCount!]=%%~x"
)
echo Number of processed arguments: %argCount%

set serialNumberSection=2
for /L %%i in (2,2,%argCount%) do (
    echo %%i- "!argVec[%%i]!"
    set /A serialNumberSection+=1
    echo %%serialNumberSection !argVec[%%serialNumberSection]!
)

My output

Number of processed arguments: 9
2- "0xAA"
%serialNumberSection <=Expected: 0x33323130
4- "0xBB"
%serialNumberSection <=Expected: 0x37363534 
6- "0xCC"
%serialNumberSection <=Expected: 0x42413938 
8- "0xDD"
%serialNumberSection <=Expected: 0x46454443
aschipfl
  • 33,626
  • 12
  • 54
  • 99
ndarkness
  • 1,011
  • 2
  • 16
  • 36
  • 1
    `%%serialNumberSection` is your issue, a `%variable%` uses slightly different batch file syntax to the `%%metavariable`. Also as its value is being updated inside the loop it too would need some form of expansion delay. – Compo Jun 18 '18 at 10:44
  • 1
    Instead of `echo %%serialNumberSection !argVec[%%serialNumberSection]!`, use either `call echo !serialNumberSection! %%argVec[!serialNumberSection!]%%` or `for %%j in (!serialNumberSection!) do echo %%j !argVec[%%j]!`... – aschipfl Jun 18 '18 at 10:46
  • 1
    This type of management is described at [this answer](https://stackoverflow.com/questions/10166386/arrays-linked-lists-and-other-data-structures-in-cmd-exe-batch-script/10167990#10167990) – Aacini Jun 18 '18 at 12:37
  • @Aacini, I already referred to this post in my answer below... ;-) – aschipfl Jun 18 '18 at 12:43

1 Answers1

3

Instead of the line:

echo %%serialNumberSection !argVec[%%serialNumberSection]!

use either:

call echo !serialNumberSection! %%argVec[!serialNumberSection!]%%

or:

for %%j in (!serialNumberSection!) do echo %%j !argVec[%%j]!

%%serialNumberSection is wrong syntax, because the prefix %% is only valid for for variable references (like your %%i), but serialNumberSection is a normal environment variable.

%serialNumberSection% does not work, because you are updating the variable inside the loop.

!serialNumberSection! works, but not to expand your array elements, because delayed expansion cannot be nested (so !argVec[!serialNumberSection!]! fails as it tries to expand variables argVec[ and ], and serialNumberSection is considered as a literal string), hence you need to work around that.

Reference also this articles:

aschipfl
  • 33,626
  • 12
  • 54
  • 99
  • Thanks @aschipfl, one more question if I would like to use those values as input to a binary, something like `my.exe !argVec[%%i]! call echo !serialNumberSection! %%argVec[!serialNumberSection!]%%` should I use the `call echo` or the `for %%j ...` to address the second parameter? – ndarkness Jun 18 '18 at 10:57
  • 1
    I would use this (inside your `for /L %%i` loop): `for %%j in (!serialNumberSection!) do my.exe !argVec[%%i]! !argVec[%%j]!` (because it is more obvious and it may be faster than `call`; if you want to use `call`, try this: `call my.exe !argVec[%%i]! %%argVec[!serialNumberSection!]%%`) – aschipfl Jun 18 '18 at 11:01