2

I wanted to create my own "stringLength" script and I managed to do it but I do not understand one line of code that I borrowed from https://ss64.com/nt/syntax-substring.html ( check near the bottom of the page )

My script is:

@echo off

::initializing variables
SET strlen=0
SET "string=stringToBeMeasured"
:: adding } at the end of the string to signal the end of the count
set "string=%string%}"

:main

    call SET chosenchar=%%string:~%strlen%,1%%
:: if the character is not } then add string lenght +1 until... 
    if "%chosenchar%" neq "}" ( 
        set /a strlen=%strlen%+1 
        goto :main
    )
:: when you see the designated } character, then print the result and exit
    if "%chosenchar%" == "}" ( goto :exit )

:exit
echo Your string length is: %strlen%
pause

And the line I do not understand how exactly works is:

call SET chosenchar=%%string:~%strlen%,1%%

Why do I have to CALL it and not just SET it? Can you guide me with a lot of details?

Thanks in advance!

Cheper
  • 21
  • 1
  • What happens when you remove CALL from that statement? – Br.Bill Jun 30 '23 at 19:05
  • @Br.Bill it does just hangs... – Cheper Jun 30 '23 at 19:07
  • You have a variable inside another variable. so you need a way to first evaluate the inner variable and then evaluate the outer variable (with the inner variable replaced by its value). `Call` is one way to add this second layer of parsing. See [here](https://stackoverflow.com/a/30284028/2152082) for more information and other ways to do it. (And [here](https://stackoverflow.com/questions/4094699/how-does-the-windows-command-interpreter-cmd-exe-parse-scripts) for the complete rabbit hole of parsing) – Stephan Jun 30 '23 at 19:26

2 Answers2

2

It forces a second expansion of the variables. One for the command itself , the second one when the call is executed. When delayed expansion is not used this is a way to cause a nestest expansion of the variables. Here's an example from SS64 (https://ss64.com/nt/call.html#advanced):

 @Echo off
 SETLOCAL
 set _server=frodo
 set _var=_server
 CALL SET _result=%%%_var%%%
 echo %_result%

In this case it is used to expand %strlen% in substring expression : https://ss64.com/nt/syntax-substring.html

npocmaka
  • 55,367
  • 18
  • 148
  • 187
0

Quoting from the site you linked:

You can use the :~ syntax and provide each of the parameters from other variables, for example if you have

%_donor%=2539850

%_digit%=4

To extract digit # 4 from _donor you might try

SET _substring=%_donor:~%_digit%,1%

Unfortunately this will not work because the :~ syntax expects a value not a variable. To get around this use the CALL command (...)

The CALL command forces the %_digit% value to be evaluated before the SET command executes. Without using CALL, the peculiarities of this :~ syntax lead the shell to try to read the characters %_digit% as a number, which doesn't work.

Not sure why failure to use CALL leads to a hang, though; temporarily adding @ECHO ON on the line above :main should give you feedback as to where the hang is taking place.

Br.Bill
  • 637
  • 5
  • 12
  • 1
    Thanks for your answer. I managed to remove `call` by enabling delayed expansion and I edited it like as: `SET chosenchar=!string:~%strlen%,1!`. If I am being honest I am closer to understanding the concept but not exactly there yet. I will read all of the links you all kindly provided and return here if I want extra info! – Cheper Jun 30 '23 at 22:17