'Windows Batch: Split String to individual characters to variables

in Windows Batch, if I had a variable (length can change) that was, for example: "hello world!" is it possible to "split" the variable so each character is its own variable so the output could look like:

t1=h
t2=e
t3=l
etc.

Any help would be appreciated.



Solution 1:[1]

Use this code:

setlocal EnableDelayedExpansion
set str="hello world^!"
set tempstr=%str%
set count=0
:loop
if defined tempstr (
    set tempstr=%tempstr:~1%
    set /a count+=1
    set /a pos=%count%-1
    set t!count!=!str:~%pos%,1!
    goto loop
)

:: check the generated variables
set t

To get the nth character in a string, use set char=%str:~n,1%.
I hope this was helpful!

Solution 2:[2]

Here is a variant using for /L to iterate over all characters of the string. The number of characters, so the length of the string, is retrieved in sub-routine :LENGTH first:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_STRING=Hello world!"

call :LENGTH LEN "%_STRING%"
setlocal EnableDelayedExpansion
for /L %%I in (0,1,%LEN%) do (
    set "$CHR[%%I]=!_STRING:~%%I,1!"
)
set $CHR
endlocal

endlocal
exit /B


:LENGTH  rtn_length  val_string
setlocal DisableDelayedExpansion
set /A "RET=0" & set "STR=%~2"
if defined STR set /A "RET=1"
setlocal EnableDelayedExpansion
for %%L in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
    if not "!STR:~%%L,1!"=="" (
        set /A "RET+=%%L"
        set "STR=!STR:~%%L!"
    )
)
(
    endlocal
    endlocal
    set "%~1=%RET%"
)
exit /B

Here is a different variant, using cmd /U to convert the string into Unicode, where a null-byte becomers inserted behind every character, and find, which treats these null-bytes like end-of-line markers:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_STRING=Hello world!"

set /A "IDX=0"
for /F delims^=^ eol^= %%I in ('
    cmd /U /V /C echo^(!_STRING!^| find /V ""
') do (
    set "CHR=%%I"
    setlocal EnableDelayedExpansion
    for /F "delims=" %%J in ("$CHR[!IDX!]=!CHR!") do (
        endlocal
        set "%%J"
    )
    set /A "IDX+=1"
)
set $CHR

endlocal
exit /B

Finally, here is another variant, based on a goto loop. This uses a position pointer POS to scan the string and to extract a single character. If no character is returned, the end of the string is reached:

@echo off
setlocal EnableExtensions DisableDelayedExpansion

rem // Define constants here:
set "_STRING=Hello world!"

setlocal EnableDelayedExpansion
if not defined _STRING goto :QUIT
set /A "POS=0"
:LOOP
set "CHR=!_STRING:~%POS%,1!"
if defined CHR (
    set "$CHR[%POS%]=!CHR!"
    set /A "POS+=1"
    goto :LOOP
)
:QUIT
set $CHR
endlocal

endlocal
exit /B

Solution 3:[3]

Old thread, but accepted answer misses letter d? Changed

set /a pos=%count%-1 to

set /a pos=!count!-1

setlocal EnableDelayedExpansion
set str="hello world!"
set tempstr=%str%
set count=0
:loop
if defined tempstr (
    set tempstr=%tempstr:~1%
    set /a count+=1
    set /a pos=!count!-1
    set t!count!=!str:~%pos%,1!
    goto loop
)

:: check the generated variables
set t
pause

Here is another version. variables start with 0, though

setlocal EnableDelayedExpansion
set var="hello world!"
rem remove quotes
set var=%var:"=%

rem add limiter
set var=%var%_

echo %var%

set count=0

:loop
set tempvar=!var:~%count%,1!
if !tempvar!==_ goto skip
set arr!count!=!tempvar!
set /a count=!count!+1
goto loop

:skip
echo out

echo display output
set arr

pause

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 the liquid metal
Solution 2
Solution 3 user17014487