Sonntag, 25. November 2007

BATCH_ String length

This little subroutine calculates the string length in Batch (cmd.exe) using the divide and conquer algorithm. It starts with the maximum string length possible under Windows XP (4191, NT and 2000 are limited to 2047, see http://support.microsoft.com/kb/830473). It divides the string in two equal halfs and tests if the character in the middle exists. If not, does that again with the left half, if it does, stores the length including that character and starts of for the rest of the string.
:: Returns the string length.
:: PARAM
:: 1 String string to get length of
:: RETURN Integer string length
:STRLEN
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
SET STR="%~1"& SET STR=!STR:~1,-1!
SET LEN=0
:: Max string length is 8191, see http://support.microsoft.com/kb/830473
SET POS=8192
:STRLEN_LOOP
SET /A POS /= 2
IF NOT "!STR!" == "" (
    IF NOT "!STR:~%POS%,1!" == "" (
        SET /A LEN += %POS% + 1
        :: work on rest, that is after POS+1
        SET STR=!STR:~%POS%!
        SET STR=!STR:~1!
    )
    GOTO :STRLEN_LOOP
)
ENDLOCAL & SET RESULT=%LEN%
GOTO :EOF
I have to double check the string because substring extraction %STR:~x,y% on an empty string leaves you with ~x,y. However, extracting a substring after the end of a non-empty string works as expected and returns the empty string.

I did some performance testing, and though jumping to labels is heavily dependent of script layout and size, 100 calculations of a string no matter what length lasted about 1 sec and 300 ms on an AMD Athlon XP 3200+.

If you are using only very short strings, you can loop through each character and test it for existence:
:: Calculates the string length of the first parameter.
:: PARAM
:: 1 String to return length of
:: RESULT Integer length of tring
:STRLEN
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
SET I=-1
SET T=%~1
:STRLEN_LOOP
SET /A I += 1
IF NOT "!T!" == "" IF NOT "!T!" == "!T:~0,%I%!" (
    GOTO :STRLEN_LOOP
)
ENDLOCAL & SET RESULT=%I%
GOTO :EOF
However, the cost scales with the string length. Compared with the first solution, it is faster (less than 1 second for 100 tests) for strings shorter than 10 characters, and for 16 characters takes exactly the same amount of time.
Ricardo Leite (Gast) - 2. Jun, 18:36

Perfect code

Hi! Thanks for this brilliant code.
It's very useful. But I only see a problem when strings contains "&" characters. Please, could you improve the 1st code to process "&" as part of the string?
I'll be very thankful.

Reflog

Informationstechnische Howtos, Hinweise und Merkwürdiges

Batchlib v1.0 2008-03-29

Aktuelle Beiträge

HOWTO_ O2 DSL Surf &...
Der O2 DSL Surf & Phone-Router ist für die alleinige...
cypressor - 12. Feb, 19:57
Uptweak Windows XP Home...
There are a lot of annoying limitations in Windows...
cypressor - 9. Okt, 19:30
BATCHLIB_ Batchlib package...
Download Batchlib package v1.0 (5 KB zip file) What...
cypressor - 29. Mär, 19:10
BATCHLIB_ Batchlib library...
The batchlib library string.cmd is part of the batchlib...
cypressor - 29. Mär, 18:10

Homepage Ticker

Links

Status

Online seit 6784 Tagen
Zuletzt aktualisiert: 28. Jun, 11:32
RSS XML 1.0 Button-Get-Firefox

batch
batchlib
howto
tech
video
Profil
Abmelden
Weblog abonnieren