2

I'm trying to print a formatted string for which I require to find the length of the string. I've looked at various methods on this site, but none of them seem to work when called to work within a loop.

I am trying to customize Elias Bachaalany's code which prints out all stored Windows Wifi passwords. The section in question is below.

   call :get-profiles r

    :: For each profile, try to get the password
    :main-next-profile
        for /f "tokens=1* delims=," %%a in ("%r%") do (
            call :get-profile-key "%%a" key
            echo WiFi: [%%a] Password: [!key!]

            set r=%%b
        )
        if "%r%" NEQ "" goto main-next-profile

    pause

I thought it would be as simple as adding an internal loop to count the number of characters in the variable %%a:

    call :get-profiles r

    REM For each profile, try to get the password
    :main-next-profile
        for /f "tokens=1* delims=," %%a in ("%r%") do (
            call :get-profile-key "%%a" key
            echo WiFi: %%a Password: !key!

            set len=0
            set wifiname=%%a

            :getlen
                call set substring=%%wifiname:~%len%,1%%
                set /a len+=1
                echo Len:!len! A:%%a WFN:!wifiname! SS:!substring!
                if "!substring!" NEQ "" goto getlen

            pause

            set r=%%b
        )
        if "%r%" NEQ "" goto main-next-profile

    pause

With the code above I get an output as shown:

    WiFi: NOC-Guest Password:xyz
    Len:1 A:NOC-Guest WFN:NOC-Guest SS:N
    Len:2 A:%a WFN:NOC-Guest SS:O
    Len:3 A:%a WFN:NOC-Guest SS:C
    Len:4 A:%a WFN:NOC-Guest SS:-
    Len:5 A:%a WFN:NOC-Guest SS:G
    Len:6 A:%a WFN:NOC-Guest SS:u
    Len:7 A:%a WFN:NOC-Guest SS:e
    Len:8 A:%a WFN:NOC-Guest SS:s
    Len:9 A:%a WFN:NOC-Guest SS:t
    Len:10 A:%a WFN:NOC-Guest SS:
    Press any key to continue . . .
    WiFi: %b Password:
    Len:1 A:%b WFN:%b SS:
    Press any key to continue . . .
    Press any key to continue . . .

It looks like the variable %%a populates correctly on first iteration of this internal loop, but then loses its way on the second iteration. If I execute the code without the internal loop (and just the echo WiFi: %%a Password: !key! command), the Wifi list prints perfectly.

What am I doing wrong? I am somewhat aware of enabledelayedexpansion, but this seems more like a problem of variables not being persistent across subroutines.

Full original code available here

  • It does not appear you have truly done your research, otherwise you would understand :labels cannot be used WITHIN a for loop - It breaks the For loop. – T3RR0R Mar 22 '20 at 13:57
  • However, you can pass the string to a subroutine outside the for loop using `Call :label %string%`, determine the string length, and use exit /b within the subroutine to resume the for loop. – T3RR0R Mar 22 '20 at 14:00
  • 1
    [DosTips](https://www.dostips.com/) offers lots of functions (subroutines) which can be put into a batch file and called including [strlen](https://www.dostips.com/?t=Function.strLen). In many cases it is easier to append to a string value of an environment variable a fixed number of spaces and then use a string substitution to get the first X characters from the string value for an aligned output on maximum string length is known, i.e. something like `set "WiFiName=%%a                    "` and `echo WiFi: !WiFiName:~0,20! Password: !key!` which assumes no WiFi name is longer than 20 chars. – Mofi Mar 22 '20 at 14:26
  • 1
    Attention: Windows command processor does not support labels inside a command block starting with `(` and ending with matching `)`. A subroutine like `strlen` or `getlen` must be outside any command block. For the reasons read the answer on [How does the Windows Command Interpreter (CMD.EXE) parse scripts?](https://stackoverflow.com/questions/4094699/) – Mofi Mar 22 '20 at 14:28
  • Thanks T3RR0R and Mofi! I think I'll go the subroutine way. – Rohit de Sa Mar 22 '20 at 15:36

0 Answers0