0

Windows Batch: Split String to individual characters to variables

Trying to do this but in a function of its own.

I have a 4 digit number that I am trying to split into distinct variables but If there is a way to do it so that it would work for someone who doesn't know how many variables they are using I would prefer that. The following is my code so far.

REM @echo off
setlocal
:start
set /p nStore="Enter 4 digit store number:"
call :split nStore n1 n2 n3 n4
:pass2
echo %result%
echo %n1%
goto :eof

:split <nStore> <n1> <n2> <n3> <n4>
(
    setlocal EnableDelayedExpansion
    set "tmpStore=!%~1!"
    set "count=0"
    :loop
    if defined tmpStore
    (
        set tmpStore=%tmpStore:~1%
        set /a count+=1
        set /a pos=%count%-1
        set n!count!=!str:~%pos%,1!
        goto loop
    )
    endlocal
    goto :pass2
)

When I call the :split I keep getting an error "The Syntax of the command is incorrect". Right now I am trying to get :split to store my 4 digit "store number" into variables. So if my store number is 9876 I expect n1 = 9 n2 = 8 n3 = 7 n4 = 6 as variables. Question being what is wrong with my code that it errors out.

Community
  • 1
  • 1
  • That's nonsense code, a goto can't pass an argument use call instead. –  Apr 07 '17 at 18:47
  • Bah! Sorry about that. Should be fixed now – Jacob A. A. Mulberry Apr 07 '17 at 18:54
  • 2
    And what is the question? –  Apr 07 '17 at 19:34
  • Keeps saying that the syntax of the command is incorrect. I can't get it to work. :/ – Jacob A. A. Mulberry Apr 07 '17 at 19:36
  • You should read what a [mcve] is. I don't know what you expect or try to achieve. –  Apr 07 '17 at 20:32
  • In general: [**Never** use `:label` nor `:: label-like comment` inside a command block enclosed in `()` parentheses](http://stackoverflow.com/a/32147995/3439404). Remove `()` surrounding body of `:split` procedure. **2**. Remove all `<` and `>` from `:split ` line (`:split` should be necessary and sufficient). **3**. return from a procedure using `goto :eof` instead of `goto :pass2`. **4**. Think about `endlocal` inside the `:split` procedure. **5**. , **6**., … – JosefZ Apr 08 '17 at 07:34

1 Answers1

1
@ECHO OFF
SETLOCAL
REM @echo off
setlocal
:start
set /p nStore="Enter 4 digit store number:"
call :split nStore n1 n2 n3 n4
:pass2
echo %result%
echo %nstore% %n1% %n2% %n3% %n4%
goto :eof

:split <nStore> <n1> <n2> <n3> <n4>
setlocal EnableDelayedExpansion
set "n4=!%~1!"
endlocal&SET "n4=%n4%"
SET "n1=%n4:~0,1%"
SET "n2=%n4:~1,1%"
SET "n3=%n4:~2,1%"
SET "n4=%n4:~3,1%"
GOTO :EOF

You don't need to send the destination parameter names to the subprocedure. You could send %nstore% instead of nstore to avoid needing to invoke delayed expansion

...actually, you could avoid delayedexpansion using

for /f "tokens=1,2delims==" %%a in (`set %1`) do if /i "%%a"=="%1" set "n4=%%b"

If using delayedexpansion, you need the endlocal... to make the value of n4 available outside of the setlocal/endlocal bracket.

Theremainder of the code is self-evident. You aren't setting result, so that echo will resolve to echo hence provide an echo-status report. I've changed the second echo to provide a list of all of the variables in question.

And of course there's no checking done that the input data is of length 4 or of only-numerics.

Magoo
  • 77,302
  • 8
  • 62
  • 84
  • I removed the checking due to Lotpings Comment of minimal code usage to explain the problem. Accidently left `result` in there. I have it in my current script and it works. This works! Thank you. Why does GOTO: EOF work instead of going back up to something like :pass2? – Jacob A. A. Mulberry Apr 08 '17 at 13:41
  • A `call` statement transfers execution to the target label and processing then continues until you either reach end-of-file or an `exit` statement, at which point it will return to the statement following the `call`. I habitually add `goto :eof` even where it is redundant in order that I don't need to remember to insert it before any new subroutines I may add to the code. `exit` comes in a number of flavours. `exit` unadorned will terminate the `cmd` session. `exit /b n` where `n` is optional and numeric will set `errorlevel` to `n` and terminate a subroutine. – Magoo Apr 08 '17 at 14:42
  • Thanks! That helps me alot. Sorry for the basic understanding. This helps with other parts of the script I haven't gotten to yet. – Jacob A. A. Mulberry Apr 08 '17 at 15:06