Take the 2-minute tour ×

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


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 )

share|improve this question
You mean, you want to do serious programming with batch? As the meme says, "you must be new here..." –  Matteo Italia Apr 15 '12 at 21:44
@MatteoItalia linux shell has it, powershell ( based on .net ) has it, don't know about Windows CScript.exe, does it have or not? –  user1131997 Apr 15 '12 at 21:50
Although leaked, that's copyrighted material, and I'm quite sure it's illegal to have a link to them here... –  Matteo Italia Apr 15 '12 at 22:40
@MatteoItalia Have removed links :) –  user1131997 Apr 15 '12 at 22:44
This should be funny, but it is really sad instead: most answers got 13 upvotes in despite they did NOT answered the question. In my opinion, an answer that just criticize the topic with words like "idiotic", "terribly hackish", "bizarre" and similar terms have not any value at all. Note that I am NOT criticizing that answers nor defending Batch. I just can't see what is the supposed merit of that answers to deserve such amount of upvotes! I wonder if similar criticizing answers to Power Shell, VBS scripts, Phyton, Ruby, Pearl, PHP etc. topics would receive similar amount of upvotes... :( –  Aacini Apr 19 '12 at 19:42
show 1 more comment

5 Answers

Ok. I'll try to be as clearer as possible to not be misunderstood...

In Windows Batch files a variable name should begin with letter and may include any valid character, where valid characters are: #$'()*+,-.?@[]_`{}~ besides letters and digits.

This means that from cmd.exe point of view, SET NORMAL_NAME=123 is exactly the same than SET A#$'()*+,-.?@[\]_{}~=123 and also than SET VECTOR[1]=123; all three are normal variables. This way, is up to you to write variable names in the form of array elements:

set elem[1]=First element
set elem[2]=Second one
set elem[3]=The third one

This way, echo %elem[2]% will show Second one.

If you want to use another variable as index, then you must know that the replacement of variables enclosed in percents by their values is parsed from left to right; this mean that:

set i=2
echo %elem[%i%]%

don't give the desired result because it mean: show the value of elem[ variable, followed by i, followed by the value of ] variable.

To solve this problem you must use Delayed Expansion, that is, insert setlocal EnableDelayedExpansion command at beginning, enclose index variables in percents, and enclose array elements in exclamation marks:

setlocal EnableDelayedExpansion
set elem[1]=First element
set elem[2]=Second one
set elem[3]=The third one
set i=2
echo !elem[%i%]!

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 change inside FOR/IF enclose the element in double percents and precede the command with call. For example, to move a range of array elements four places to left:

for /L %%i in (%start%,1,%end%) do (
   set /A j=%%i + 4
   call set elem[%%i]=%%elem[!j!]%%

Another way to achieve previous process is using 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 run faster than previous CALL:

   set /A j=%%i + 4
   for %%j in (!j!) do set elem[%%i]=!elem[%%j]!

This way, Batch files behaves like it manage arrays. I think the important point here is not to discuss if Batch manage arrays or not, but the fact that you may manage arrays in Batch files in an equivalent way of other programming languages.

@echo off
setlocal EnableDelayedExpansion

rem Create vector with names of days
set i=0
for %%d in (Sunday Monday Tuesday Wednesday Thrusday Friday Saturday) do (
   set /A i=i+1
   set day[!i!]=%%d

rem Get current date and calculate DayOfWeek
for /F "tokens=1-3 delims=/" %%a in ("%date%") do (
   set /A mm=10%%a %% 100, dd=10%%b %% 100, yy=%%c
if %mm% lss 3 set /A mm=mm+12, yy=yy-1
set /A a=yy/100, b=a/4, c=2-a+b, e=36525*(yy+4716)/100, f=306*(mm+1)/10, jdn=c+dd+e+f-1523, dow=jdn %% 7 + 1
echo Today is !day[%dow%]!, %date%

Note that index values are not restricted to be numeric values as in other languages, but they may be any string that contain valid characters. Note also that the space is a valid character in variable names, so set a = 10 create "a " variable with " 10" value, so echo "%a%" will show "" and echo "%a %" will show " 10".

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 read a text file and store the indexes of the lines in a vector, then do 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 assemble a large data structure taken from a subdirectory and display it in the form of TREE command.

share|improve this answer
add comment

Seriously speaking: I never heard that batch has arrays, maybe you can emulate them with some strange trick, but I wouldn't call it a good idea.

References/instances/structs are stuff for a real language, cmd scripting is just a bunch of extensions that grew over the very primitive interpreter that was command.com, you can do some basic scripting, but anything more complicated than a bunch of calls to other commands is doomed to become ugly and incomprehensible.

The only "advanced" construct is the do-it-all weirdo for loop, which, mixed with the strange "rules" of variable substitution (%var%, %%var, !var!, are different stuff because of the idiotic parser), makes writing even trivial algorithms a collection of strange hacks (see e.g. here for an implementation of quicksort).

My tip is, if you want to do your scripting in a sane way, use a real scripting language, and leave batch for simple, quick hacks and for backwards compatibility.

share|improve this answer
msfn.org/board/topic/47265-making-arrays-in-batch here are the samples –  user1131997 Apr 15 '12 at 21:56
That's not an array, that's a single string variable that contains dot-delimited values, split with a for loop. A collection of set/for hacks, exactly as I said. Would you do anything serious in these conditions? –  Matteo Italia Apr 15 '12 at 21:58
maybe , there is a way to emulate some data structures like linked lists? maybe references can be emulated with some internal marks? –  user1131997 Apr 15 '12 at 22:02
Yep, the for command is about as close as you're going to get. And what a pain it is to work with. –  Dominic P Apr 15 '12 at 22:03
@magesi: maybe, but what's the gain from working in a language that doesn't give you even the basic tools to work with? –  Matteo Italia Apr 15 '12 at 22:05
show 3 more comments

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 variables VAR_1, VAR_2, VAR_3... using a loop and filtering on the prefix VAR_, or creating a delimited string and then using the FOR 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.

share|improve this answer
What do yo mean under serious? Could cmd.exe be defined as full by Turing Machine definition? –  user1131997 Apr 15 '12 at 22:08
@magesi: even Brainfuck, Whitespace, INTERCAL and Malbolge are Turing-complete, but I don't think you can do any real work with them. –  Matteo Italia Apr 15 '12 at 22:09
@magesi Sure it's a Turing Machine (subject to the limitations of your computer -- Turing Machines have infinite memory). But Turing Machines don't have arrays or structs either. They just have characters on a tape. Honestly, if you're just "bored w/ c++", you can go in two directions -- lisp or Brainfuck. CMD isn't a fun choice (IMO). –  trutheality Apr 15 '12 at 22:16
@magesi CMD does have ONE thing going for it -- the FOR command. If you really want to learn CMD, master that and move on. –  trutheality Apr 15 '12 at 22:19
@magesi: a more useful but crazy enough work would be to reverse-engineer every strange bit of batch syntax (I don't think there's an official specification even at Microsoft) and fix up the cmd.exe from the Wine project. :) –  Matteo Italia Apr 15 '12 at 22:31
show 5 more comments

There are no arrays, linked lists, associative arrays in Windows batch. There is, however, the most arcane, bizarre, counter-intuitive syntax I have ever come across. Seriously, you need to use a real scripting language for this. Anything but batch.

share|improve this answer
add comment

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.

:: Bubblesort
:: Horribly inefficient for large lists
:: Dave Johnson implementation 05/04/2013
@echo off
setlocal enabledelayedexpansion
:: Number of entries to populate and sort
set maxvalue=50
:: Fill a list of vars with Random numbers and print them
for /l %%a in (1,1,%maxvalue%) do (
    set /a tosort%%a=!random!
:: echo them
set tosort
:: Commence bubble sort
Echo Sorting...
set /a maxvalue-=1
set iterations=0
for /l %%a in (%maxvalue%,-1,1) do ( REM Decrease by 1 the number of checks each time as the top value will always float to the end
    set hasswapped=0
        for /l %%b in (1,1,%%a) do (
            set /a next=%%b+1
            set next=tosort!next!
            set next=!next!
            call :grabvalues tosort%%b !next!
            rem echo comparing tosort%%b = !tosortvalue! and !next! = !nextvalue!
            if !nextvalue! LSS !tosortvalue! (
            rem set /a num_of_swaps+=1
            rem echo Swapping !num_of_swaps!
                set !next!=!tosortvalue!
                set tosort%%b=!nextvalue!
                set /a hasswapped+=1
    set /a iterations+=1
    if !hasswapped!==0 goto sorted
set tosortvalue=!%1!
set nextvalue=!%2!
::nice one our kid
set tosortvalue=
echo Iterations required: %iterations%
set tosort
share|improve this answer
Excuse me. I don't like your "pseudo-arrays" reference. An array is mainly a concept: a set of elements with same name that are selected via an index. Your program may manage an array or may not; there is not such "pseudo-array" thing. See my previous link for further details... –  Aacini Apr 13 at 3:08
add comment

Your Answer

