Page 2 of 2

Re: Split string to characters

Posted: 29 Mar 2012 00:28
by foxidrive
jeb wrote:No, CALL does not run an extra CMD processor, it only restarts a new parser loop (and stops after the special character phase).

Many years ago that was the explanation.

Call has also some side effects, it's very slow and it doubles all carets, for more you could read
CALL me, or better avoid call


Re: Split string to characters

Posted: 28 Dec 2017 10:53
by Sponge Belly
Hello All,

Sorry I’m late to the party, but here’s my proffered solution to this hoary old chestnut of a problem:

Code: Select all

@echo off & setLocal enableExtensions disableDelayedExpansion
(call;) %= sets errorLevel to 0 =%

set "testStr=uncopyrightable"
call :splitStr testStr
if errorLevel 1 (
    >&2 echo(string is %errorLevel% char(s^) in length
) else (
    >&2 echo(empty string
    goto die
) %= if =%
goto end

(call) %= sets errorLevel to 1 =%
endLocal & goto :EOF

:splitStr string=
:: outputs string one character per line
setLocal disableDelayedExpansion
set "var=%1"

set "chrCount=0" & if defined var for /f "delims=" %%A in ('
    cmd /v:on /q /c for /l %%I in (0 1 8190^) do ^
    if "!%var%:~%%I,1!" neq "" (^
    echo(:^!%var%:~%%I^,1^!^) else exit 0
') do (
    set /a chrCount+=1
) %= for /f =%

endLocal & exit /b %chrCount%
The subroutine is expansion-insensitive, has no goto loop, and prints every character including CR and LF.

Happy 2018! :)

- SB

Re: Split string to characters

Posted: 28 Dec 2017 19:47
by penpen
If i see it right, then you could minimize your key idea:

Code: Select all

@echo off
setlocal enableExtensions disableDelayedExpansion
set "testStr=some text"

%ComSpec% /d /q /e:on /v:on /cif defined testStr for /L %%a in (0, 1, 8190) do if "!testStr:~%%~a,1!" == "" (exit) else echo(!testStr:~%%~a,1!

goto :eof
There's also a solution (basing on jebs strLen algorithm idea) without using call or cmd.exe:

Code: Select all

@echo off
setlocal enableExtensions enableDelayedExpansion
set "s=some text"

if not defined s goto :eof
set "i=4096"
2>nul set /a "i+=2048, i-!s:~%i%,1!=4096"
2>nul set /a "i+=1024, i-!s:~%i%,1!=2048"
2>nul set /a "i+=512, i-!s:~%i%,1!=1024"
2>nul set /a "i+=256, i-!s:~%i%,1!=512"
2>nul set /a "i+=128, i-!s:~%i%,1!=256"
2>nul set /a "i+=64, i-!s:~%i%,1!=128"
2>nul set /a "i+=32, i-!s:~%i%,1!=64"
2>nul set /a "i+=16, i-!s:~%i%,1!=32"
2>nul set /a "i+=8, i-!s:~%i%,1!=16"
2>nul set /a "i+=4, i-!s:~%i%,1!=8"
2>nul set /a "i+=2, i-!s:~%i%,1!=4"
2>nul set /a "i+=1, i-!s:~%i%,1!=2"
2>nul set /a "i-!s:~%i%,1!=1"

for /l %%a in (0, 1, %i%) do echo(!s:~%%~a,1!

goto :eof

Re: Split string to characters

Posted: 01 Jan 2018 04:43
by Sponge Belly
Hello Penpen and Happy 2018! :)

Your first solution is very reductionist… I love it! 8)

My only criticism is that it prints 2 newlines for a single LF.

As for your second solution, I’m still trying to figure it out. :lol:

Thanks for your feedback.

- SB