I am attempting to write a routine that builds a string consisting of a single character repeated N times, up to the maximum variable length of 8191.
It works great until it reaches a length 8184. Then it fails for lengths 8185 - 8191

I added some diagnostic messages, and it turns out I am not able to append a character to a string that is length 8184


I thought I had seen a variable with length 8191 before. Am I crazy

Why can't I append to a variable length 8184

Do I have to compensate for the length of the variable name and/or the command line length

I would have thought that delayed expansion would eliminate the worry about the command line length.
Code: Select all
@echo off
:buildString
setlocal enableDelayedExpansion
if %~1 geq 8192 exit /b
set /a "n=%~1, leftBit=4096"
set "str="
echo target len=!n!
for /l %%n in (1 1 13) do (
echo(
call :strLen str len
echo before double len=!len!
set "str=!str!!str!"
call :strLen str len
echo after double len=!len!
set /a "bit=n&leftBit, n<<=1"
if !bit! neq 0 (
set "str=!str!."
call :strLen str len
echo after append len=!len!
)
)
exit /b
echo(
call :strLen str len
echo final len=!len!
exit /b
:strLen string len -- returns the length of a string
:: -- string [in] - variable name containing the string being measured for length
:: -- len [out] - variable to be used to return the string length
:: Many thanks to 'sowgtsoi', but also 'jeb' and 'amel27' dostips forum users helped making this short and efficient
:$created 20081122 :$changed 20101116 :$categories StringOperation
:$source http://www.dostips.com
( SETLOCAL ENABLEDELAYEDEXPANSION
set "str=A!%~1!"&rem keep the A up front to ensure we get the length and not the upper bound
rem it also avoids trouble in case of empty string
set "len=0"
for /L %%A in (12,-1,0) do (
set /a "len|=1<<%%A"
for %%B in (!len!) do if "!str:~%%B,1!"=="" set /a "len&=~1<<%%A"
)
)
( ENDLOCAL & REM RETURN VALUES
IF "%~2" NEQ "" SET /a %~2=%len%
)
EXIT /b
output:
Code: Select all
>buildstring 8185
target len=8185
before double len=0
after double len=0
after append len=1
before double len=1
after double len=2
after append len=3
before double len=3
after double len=6
after append len=7
before double len=7
after double len=14
after append len=15
before double len=15
after double len=30
after append len=31
before double len=31
after double len=62
after append len=63
before double len=63
after double len=126
after append len=127
before double len=127
after double len=254
after append len=255
before double len=255
after double len=510
after append len=511
before double len=511
after double len=1022
after append len=1023
before double len=1023
after double len=2046
before double len=2046
after double len=4092
before double len=4092
after double len=8184
after append len=8184