Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 279 Vote(s) - 3.47 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How do you get the string length in a batch file?

#1
There doesn't appear to be an easy way to get the length of a string in a batch file. E.g.,

SET MY_STRING=abcdefg
SET /A MY_STRING_LEN=???

How would I find the string length of `MY_STRING`?

Bonus points if the string length function handles all possible characters in strings including escape characters, like this: `!%^^()^!`.
Reply

#2
Yes, of course there's an easy way, using vbscript (or powershell).

WScript.Echo Len( WScript.Arguments(0) )

save this as `strlen.vbs` and on command line

c:\test> cscript //nologo strlen.vbs "abcd"

Use a for loop to capture the result ( or use vbscript entirely for your scripting task)

Certainly beats having to create cumbersome workarounds using batch and there's no excuse not to use it since vbscript is available with each Windows distribution ( and powershell in later).
Reply

#3
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.txt
FOR %%? 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
Reply

#4
I like the [two line approach][1] of jmh_gr.

It won't work with single digit numbers unless you put `()` around the portion of the command before the redirect. since `1>` is a special command "Echo is On" will be redirected to the file.

This example should take care of single digit numbers but not the other special characters such as `<` that may be in the string.

(ECHO %strvar%)> tempfile.txt




[1]:

[To see links please register here]

Reply

#5
The first few lines are simply to demonstrate the :strLen function.

@echo off
set "strToMeasure=This is a string"
call :strLen strToMeasure strlen
echo.String is %strlen% characters long
exit /b

:strLen
setlocal enabledelayedexpansion
:strLen_Loop
if not "!%1:~%len%!"=="" set /A len+=1 & goto :strLen_Loop
(endlocal & set %2=%len%)
goto :eof

Of course, this is not quite as efficient at the "13 loop" version provided by jeb. But it is easier to understand, and your 3GHz computer can slip through a few thousand iterations in a small fraction of a second.
Reply

#6
If you are on Windows Vista +, then try this Powershell method:

For /F %%L in ('Powershell $Env:MY_STRING.Length') do (
Set MY_STRING_LEN=%%L
)

or alternatively:

Powershell $Env:MY_STRING.Length > %Temp%\TmpFile.txt
Set /p MY_STRING_LEN = < %Temp%\TmpFile.txt
Del %Temp%\TmpFile.txt

I'm on Windows 7 x64 and this is working for me.


Reply

#7
Just another batch script to calculate the length of a string, in just a few lines. It may not be the fastest, but it's pretty small. The subroutine ":len" returns the length in the second parameter. The first parameter is the actual string being analysed.
Please note - special characters must be escaped, that is the case with any string in the batch file.


@echo off
setlocal
call :len "Sample text" a
echo The string has %a% characters.
endlocal
goto :eof

:len <string> <length_variable> - note: string must be quoted because it may have spaces
setlocal enabledelayedexpansion&set l=0&set str=%~1
:len_loop
set x=!str:~%l%,1!&if not defined x (endlocal&set "%~2=%l%"&goto :eof)
set /a l=%l%+1&goto :len_loop
Reply

#8
@echo off
:: warning doesn't like * ( in mystring

setlocal enabledelayedexpansion

set mystring=this is my string to be counted forty one

call :getsize %mystring%
echo count=%count% of "%mystring%"

set mystring=this is my string to be counted

call :getsize %mystring%

echo count=%count% of "%mystring%"

set mystring=this is my string
call :getsize %mystring%

echo count=%count% of "%mystring%"
echo.
pause
goto :eof

:: Get length of mystring line ######### subroutine getsize ########

:getsize

set count=0

for /l %%n in (0,1,2000) do (

set chars=

set chars=!mystring:~%%n!

if defined chars set /a count+=1
)
goto :eof

:: ############## end of subroutine getsize ########################
Reply

#9
@echo off & setlocal EnableDelayedExpansion
set Var=finding the length of strings
for /l %%A in (0,1,10000) do if not "%Var%"=="!Var:~0,%%A!" (set /a Length+=1) else (echo !Length! & pause & exit /b)

set the var to whatever you want to find the length of it or change it to set /p var= so that the user inputs it.
Putting this here for future reference.
Reply

#10
I prefer [jeb's accepted answer](

[To see links please register here]

) - 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 off
setlocal
set "test=Hello world!"

:: Echo the length of TEST
call :strLen test

:: Store the length of TEST in LEN
call :strLen test len
echo len=%len%
exit /b

:strLen strVar [rtnVar]
setlocal disableDelayedExpansion
set len=0
if 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](

[To see links please register here]

) can be adopted for use as a [batch "macro" with arguments](

[To see links please register here]

). 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](

[To see links please register 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 off
setlocal 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 continuation
set ^"\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 macro
set @strLen

:: Demonstrate usage

set "testString=this has a length of 23"

echo(
echo Testing %%@strLen%% testString
%@strLen% testString

echo(
echo Testing call :strLen testString
call :strLen testString

echo(
echo Testing %%@strLen%% testString rtn
set "rtn="
%@strLen% testString rtn
echo rtn=%rtn%

echo(
echo Testing call :strLen testString rtn
set "rtn="
call :strLen testString rtn
echo rtn=%rtn%

echo(
echo Measuring %%@strLen%% time:
set "t0=%time%"
for /l %%N in (1 1 1000) do %@strlen% testString testLength
set "t1=%time%"
call :printTime

echo(
echo Measuring CALL :strLen time:
set "t0=%time%"
for /l %%N in (1 1 1000) do call :strLen testString testLength
set "t1=%time%"
call :printTime
exit /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
)

:printTime
setlocal
for /f "tokens=1-4 delims=:.," %%a in ("%t0: =0%") do set /a "t0=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100
for /f "tokens=1-4 delims=:.," %%a in ("%t1: =0%") do set /a "t1=(((1%%a*60)+1%%b)*60+1%%c)*100+1%%d-36610100
set /a tm=t1-t0
if %tm% lss 0 set /a tm+=24*60*60*100
echo %tm:~0,-2%.%tm:~-2% msec
exit /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% testString
23

Testing call :strLen testString
23

Testing %@strLen% testString rtn
rtn=23

Testing call :strLen testString rtn
rtn=23

Measuring %@strLen% time:
1.93 msec

Measuring CALL :strLen time:
7.08 msec

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through