How do you get the string length in a batch file? How do you get the string length in a batch file? windows windows

How do you get the string length in a batch file?


As there is no built in function for string length, you can write your own function like this one:

@echo offsetlocalREM *** Some tests, to check the functionality ***REM *** An emptyStr has the length 0set "emptyString="call :strlen result emptyStringecho %result%REM *** This string has the length 14set "myString=abcdef!%%^^()^!"call :strlen result myStringecho %result%REM *** This string has the maximum length of 8191setlocal EnableDelayedExpansionset "long=."FOR /L %%n in (1 1 13) DO set "long=!long:~-4000!!long:~-4000!"(set^ longString=!long!!long:~-191!)call :strlen result longStringecho %result%goto :eofREM ********* function *****************************:strlen <resultVar> <stringVar>(       setlocal EnableDelayedExpansion    (set^ tmp=!%~2!)    if defined tmp (        set "len=1"        for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (            if "!tmp:~%%P,1!" NEQ "" (                 set /a "len+=%%P"                set "tmp=!tmp:~%%P!"            )        )    ) ELSE (        set len=0    ))(     endlocal    set "%~1=%len%"    exit /b)

This function needs always 13 loops, instead of a simple strlen function which needs strlen-loops.
It handles all characters.

The strange expression (set^ tmp=!%~2!) is necessary to handle ultra long strings, else it's not possible to copy them.


You can do it in two lines, fully in a batch file, by writing the string to a file and then getting the length of the file. You just have to subtract two bytes to account for the automatic CR+LF added to the end.

Let's say your string is in a variable called strvar:

ECHO %strvar%> tempfile.txtFOR %%? IN (tempfile.txt) DO ( SET /A strlength=%%~z? - 2 )

The length of the string is now in a variable called strlength.

In slightly more detail:

  • FOR %%? IN (filename) DO ( ... : gets info about a file
  • SET /A [variable]=[expression] : evaluate the expression numerically
  • %%~z? : Special expression to get the length of the file

To mash the whole command in one line:

ECHO %strvar%>x&FOR %%? IN (x) DO SET /A strlength=%%~z? - 2&del x


I prefer jeb's accepted answer - it is the fastest known solution and the one I use in my own scripts. (Actually there are a few additional optimizations bandied about on DosTips, but I don't think they are worth it)

But it is fun to come up with new efficient algorithms. Here is a new algorithm that uses the FINDSTR /O option:

@echo offsetlocalset "test=Hello world!":: Echo the length of TESTcall :strLen test:: Store the length of TEST in LENcall :strLen test lenecho len=%len%exit /b:strLen  strVar  [rtnVar]setlocal disableDelayedExpansionset len=0if defined %~1 for /f "delims=:" %%N in (  '"(cmd /v:on /c echo(!%~1!&echo()|findstr /o ^^"') do set /a "len=%%N-3"endlocal & if "%~2" neq "" (set %~2=%len%) else echo %len%exit /b

The code subtracts 3 because the parser juggles the command and adds a space before CMD /V /C executes it. It can be prevented by using (echo(!%~1!^^^).


For those that want the absolute fastest performance possible, jeb's answer can be adopted for use as a batch "macro" with arguments. This is an advanced batch technique devloped over at DosTips that eliminates the inherently slow process of CALLing a :subroutine. You can get more background on the concepts behind batch macros here, but that link uses a more primitive, less desirable syntax.

Below is an optimized @strLen macro, with examples showing differences between the macro and :subroutine usage, as well as differences in performance.

@echo offsetlocal disableDelayedExpansion:: -------- Begin macro definitions ----------set ^"LF=^%= This creates a variable containing a single linefeed (0x0A) character =%^":: Define %\n% to effectively issue a newline with line continuationset ^"\n=^^^%LF%%LF%^%LF%%LF%^^":: @strLen  StrVar  [RtnVar]::::   Computes the length of string in variable StrVar::   and stores the result in variable RtnVar.::   If RtnVar is is not specified, then prints the length to stdout.::set @strLen=for %%. in (1 2) do if %%.==2 (%\n%  for /f "tokens=1,2 delims=, " %%1 in ("!argv!") do ( endlocal%\n%    set "s=A!%%~1!"%\n%    set "len=0"%\n%    for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (%\n%      if "!s:~%%P,1!" neq "" (%\n%        set /a "len+=%%P"%\n%        set "s=!s:~%%P!"%\n%      )%\n%    )%\n%    for %%V in (!len!) do endlocal^&if "%%~2" neq "" (set "%%~2=%%V") else echo %%V%\n%  )%\n%) else setlocal enableDelayedExpansion^&setlocal^&set argv=,:: -------- End macro definitions ----------:: Print out definition of macroset @strLen:: Demonstrate usageset "testString=this has a length of 23"echo(echo Testing %%@strLen%% testString%@strLen% testStringecho(echo Testing call :strLen testStringcall :strLen testStringecho(echo Testing %%@strLen%% testString rtnset "rtn="%@strLen% testString rtnecho rtn=%rtn%echo(echo Testing call :strLen testString rtnset "rtn="call :strLen testString rtnecho rtn=%rtn%echo(echo Measuring %%@strLen%% time:set "t0=%time%"for /l %%N in (1 1 1000) do %@strlen% testString testLengthset "t1=%time%"call :printTimeecho(echo Measuring CALL :strLen time:set "t0=%time%"for /l %%N in (1 1 1000) do call :strLen testString testLengthset "t1=%time%"call :printTimeexit /b:strlen  StrVar  [RtnVar]:::: Computes the length of string in variable StrVar:: and stores the result in variable RtnVar.:: If RtnVar is is not specified, then prints the length to stdout.::(  setlocal EnableDelayedExpansion  set "s=A!%~1!"  set "len=0"  for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (    if "!s:~%%P,1!" neq "" (      set /a "len+=%%P"      set "s=!s:~%%P!"    )  ))(  endlocal  if "%~2" equ "" (echo %len%) else set "%~2=%len%"  exit /b):printTimesetlocalfor /f "tokens=1-4 delims=:.," %%a in ("%t0: =0%") do set /a "t0=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100for /f "tokens=1-4 delims=:.," %%a in ("%t1: =0%") do set /a "t1=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100set /a tm=t1-t0if %tm% lss 0 set /a tm+=24*60*60*100echo %tm:~0,-2%.%tm:~-2% msecexit /b

-- Sample Output --

@strLen=for %. in (1 2) do if %.==2 (  for /f "tokens=1,2 delims=, " %1 in ("!argv!") do ( endlocal    set "s=A!%~1!"    set "len=0"    for %P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (      if "!s:~%P,1!" neq "" (        set /a "len+=%P"        set "s=!s:~%P!"      )    )    for %V in (!len!) do endlocal&if "%~2" neq "" (set "%~2=%V") else echo %V  )) else setlocal enableDelayedExpansion&setlocal&set argv=,Testing %@strLen% testString23Testing call :strLen testString23Testing %@strLen% testString rtnrtn=23Testing call :strLen testString rtnrtn=23Measuring %@strLen% time:1.93 msecMeasuring CALL :strLen time:7.08 msec