I was playing with cmd.exe, but in its help I didn't find any info, how to define arrays.
I have found, how to define simple variables:
set a=10
echo %a%
But, I want to create arrays, linked list etc...
So, does it able in cmd.exe ( I mean: does in cmd.exe exist any array keywords? )
I want to realize some algorithms as:
- bubble sort
- quick sort
- gnome sort
etc...
So, I also want to know, does Cmd.exe have references or instances, structs etc?
Cause its help not full in: /?
Could Cmd.exe be defined as full by Turing-Machine definition? ( Turing-Complete )
Ok. I'll try to be as clear as possible to not be misunderstood...
In Windows Batch files a variable name should begin with a letter and may include any valid character, where valid characters are: #$'()*+,-.?@[]_`{}~ besides letters and digits.
This means that from the cmd.exe point of view,
SET NORMAL_NAME=123
is exactly the same asSET A#$'()*+,-.?@[\]_{}~=123
and also the same asSET VECTOR[1]=123
; all three are normal variables. This way, it is up to you to write variable names in the form of array elements:This way,
echo %elem[2]%
will showSecond one
.If you want to use another variable as index, you must know that the replacement of variables enclosed in percent symbols by their values is parsed from left to right; this means that:
doesn't give the desired result because it means: show the value of the
elem[
variable, followed byi
, followed by the value of the]
variable.To solve this problem you must use Delayed Expansion, that is, insert
setlocal EnableDelayedExpansion
command at the beginning, enclose index variables in percent symbols, and enclose the array elements in exclamation marks:You may also use parameters of FOR commands as indexes:
for /L %%i in (1,1,3) do echo !elem[%%i]!
. You must use !index! to store values in array elements when the index is changed inside a FOR or IF:set elem[!index!]=New value
. To get the value of an element when the index changes inside FOR/IF, enclose the element in double percent symbols and precede the command withcall
. For example, to move a range of array elements four places to the left:Another way to achieve the previous process is to use an additional FOR command to change the delayed expansion of the index by an equivalent replaceable parameter, and then use the delayed expansion for the array element. This method runs faster than previous CALL:
This way, the Batch file behaves like it manages arrays. I think the important point here is not to discuss if Batch manages arrays or not, but the fact that you may manage arrays in Batch files in an equivalent way of other programming languages.
Note that index values are not limited to numbers, but they may be any string that contain valid characters; this point allows to define what in other programming languages are called associative arrays. At this answer there is a detailed explanation of the method used to solve a problem using an associative array. Note also that the space is a valid character in variable names, so you must pay attention to not insert spaces in variable names that may go unnoticed.
I elaborated on the reasons I have to use array notation in Batch files at this post.
In this post there is a Batch file that reads a text file and stores the indexes of the lines in a vector, then does a Buble Sort of vector elements based on line contents; the equivalent result is a sort over file contents.
In this post there is a basic Relational Data Base application in Batch based on indexes stored in files.
In this post there is a complete multiple linked-list application in Batch that assembles a large data structure taken from a subdirectory and displays it in the form of TREE command.
Concerning this statement:
This is simply wrong! Variable
a
will remain empty (supposing it was empty initially) andecho %a%
will returnECHO is on.
A variable calleda
SPACE will actually be set to the value SPACE10
.So for the code to work, you must get rid of the SPACEs around the equal-to sign:
To make the assignment safe against all characters, use the quoted syntax (supposing you have the command extensions enabled, which is the default for the Windows command prompt anyway):
For all the rest of your question I recommend to read Aacini's great and comprehensive answer.
Windows shell scripting really isn't designed to work with arrays, let alone complex data structures. For the most part, everything's a string in the windows shell, but, there are some things you can do to "work with" arrays, like declaring
n
variablesVAR_1, VAR_2, VAR_3...
using a loop and filtering on the prefixVAR_
, or creating a delimited string and then using theFOR
construct that iterates over a delimited string.Similarly, you can use the same basic idea to create a struct-like set of variables like
ITEM_NAME, ITEM_DATA
or w/e. I even found this link that talks about simulating an associative array in CMD.It is all terribly hackish and inconvenient when it comes down to it. The command-line shell just wasn't designed for heavy programming. I agree with @MatteoItalia -- if you need serious scripting, use a real scripting language.
The following program simulates vectors (arrays) operations in
cmd
. The subroutines presented in it were initially designed for some special cases like storing the program parameters in an array or looping through filenames in a "for
" loop and storing them in an array. In these cases, in anenabled delayed expansion
block, the "!
" characters - if present in values of the parameters or in the "for
" loop variable's value - would get interpreted. That's why, in these cases, the subroutines must be used inside adisabled delayed expansion
block:It is also possible to store the program parameters in an "array" or loop through the filenames in a directory using a "
for
" loop and store them in an "array" (without interpreting "!
" in their values) without using the presented subroutines in the program above:I made a bubble sort implementation in batch using pseudo-arrays a while ago. Not sure why you'd use it (although I will admit to doing so in another batch file) as it gets pretty slow as the list size increases. It was more to set myself a little challenge. Someone might find this useful.