Simulate while loop in Batch - batch-file

I'm trying to simulate a while loop in Batch, here's my code:
#echo off
set test=0
:main
call:whileLSS %test% 4 :count
:whileLSS
if %1 LSS %2 (
echo %1
call%3
goto whileLSS
)
goto:EOF
:count
set /a test=%test%+1
goto:EOF
This just outputs 0s, instead of outputting "0 1 2 3" like I want it to.
The problem is that the loop goes forever because %1 doesn't have the most updated value of test.
Is this the right approach?
How do I update the value of %1?
Is there a way to not have to hardcode operators like LSS?

as you've been told, you can't change an Arg, you can take the arg as a reference and change the referenced var, this requires delayed expansion here.
Your first sub also wasn't separated from flow.
This Batch:
#echo off&Setlocal EnableDelayedExpansion
set test=0
:main
call:whileLSS test 4 :count
Goto :Eof
:whileLSS
if !%1! LSS %2 (
echo !%1!
call%3
goto whileLSS
)
goto:EOF
:count
set /a test+=1
goto:EOF
Produces this output:
0
1
2
3
Edit
The operator to the if may also be suppied as an arg:
#echo off&Setlocal EnableDelayedExpansion
set test=0
:main
call:while test LSS 4 :Increment
set test=10
call:while test GTR 4 :Decrement
Goto :Eof
:while
if !%1! %2 %3 (
echo !%1!
call %4 %1
goto while
)
goto:EOF
:Increment
set /a %1+=1
goto:EOF
:Decrement
set /a %1-=1
goto:EOF

Like this may be?
#echo off
:main
set /a a=1
set /P i=Enter i:
call:whileLSS %a% %i%
:whileLSS
echo %1
if %1 LSS %2 call:reinitialize %1 %2
goto:EOF
:reinitialize
set /a c=%1
set /a b=%c%+1
set /a d=%2
call:whileLSS %b% %d%
goto:EOF

Try this:
#echo off
Setlocal EnableDelayedExpansion
set test=0
:main
call :whileLSS !test! 4
Goto :Eof
:whileLSS
set i=%1
set j=%2
:loop
if !i! LSS !j! (
echo !i!
call :count
goto :loop
)
goto :EOF
:count
set /a i+=1
goto :EOF

Related

Return value from a cmd function

I have a batch function and I need to return a value from it. Following is the script:
#echo off
call :Mode mode1
echo mode is %mode1%
:Mode
setlocal enabledelayedexpansion
set count=0
for /f "tokens=*" %%x in (map.txt) do (
set /a count+=1
set var[!count!]=%%x
)
for /f "tokens=2 delims=: " %%A in ("%var[2]%") Do (
set mode=OPEN
)
IF %mode%==OPEN (
echo coming into open
set %1=OPEN
echo %mode1%
) ELSE (
echo coming into shorted
set %1=SHORTED
echo %mode1%
)
EXIT /B 0
echo mode is %mode1% doesn't print anything. Any help? I've hardcoded set mode=OPEN for testing purposes.
Each exit, exit /b or goto :eof implicitly does an endlocal, so you need a trick for your variable %1 to survive an endlocal. endlocal & set ... & goto :eof does the trick because the whole line gets parsed in one go:
#echo off
call :Mode mode1
echo mode is %mode1%
goto :eof
:Mode
setlocal enabledelayedexpansion
set "mode=OPEN"
IF "%mode%" == "OPEN" (
echo coming into open
endlocal&set "%1=OPEN"&goto :eof
) ELSE (
echo coming into shorted
endlocal&set "%1=SHORTED"&goto :eof
)
For the same reason, echo %mode1% in your subroutine does not print the variable.
Note: I changed set and if syntax to recommended quoted syntax.

how to random array without duplicate using batch

Im using this batch for random test1-test3 without duplicate but not working
#echo off
setlocal EnableExtensions
setlocal EnableDelayedExpansion
set /A "RND_TOTAL=3, FLAG_DUP=0"
set /A "RND_MIN=1, RND_MAX=3, RND_INTER=1"
for /L %%I in (1,1,%RND_TOTAL%) do (
call :SUB %%I
SET /A R=!RND_NUM[%%I]!
SET LINE[1]=TEST1
SET LINE[2]=TEST2
SET LINE[3]=TEST2
echo !LINE[%R%]!
pause
)
endlocal
exit /B
:SUB
set /A "RND_COUNT=%1-1"
:LOOP
set /A "RND_NUM[%1]=!RANDOM!%%((RND_MAX-RND_MIN)/RND_INTER+1)*RND_INTER+RND_MIN"
if %FLAG_DUP% EQU 0 (
for /L %%I in (1,1,%RND_COUNT%) do (
if !RND_NUM[%1]! EQU !RND_NUM[%%I]! (
goto :LOOP
)
)
)
exit /B
I get the following output:
echo off
echo off
echo off

local variable and return value of function in windows batch

#echo off
set /a n=99
echo before call test3
echo n=%n%
set ret=
call :test3 ret
echo after call test3
echo n=%n%
echo show array:
echo %ret.Array[0]%
echo %ret.Array[1]%
echo %ret.Array[2]%
echo %ret.Array[3]%
ECHO Press any key to close the windows...
pause>NUL
goto :eof
:test3
setlocal
set /a n=0
:Loop-Start
if %n% GEQ 3 goto :Loop-End
endlocal
set %~1.Array[%n%]=V%n%
setlocal
set /a n=n+1
goto :Loop-Start
:Loop-End
endlocal
goto :eof
Hi,
I have written a function test3 with local var named n, and test3 get a reference to variable named ret from caller as it parameter.
As I show in the code, I want my test3 to make an array has three elements, variable named ret in caller would hold the array.
But in caller when I print the array, I found I have not got three elements in the array.
who can help? thanks
Resolved. Following is working code for subroutine test3:
:test3
setlocal EnableDelayedExpansion
set /a n=0
for /l %%i in (0,1,3) do (
set s1=V!n!
if defined _ret (
set _ret=!_ret! ^&
)
set _ret=!_ret!set %~1.Array[!n!]=V!n!
set /a n=n+1
)
(
endlocal
%_ret%
)
goto :eof
Thanks

Variable name stored in delayed variable - Batch

I have:
setlocal EnableDelayedExpansion
var inLoopVar=hey
var first=!inLoopVar!
echo %!first!%
This outputs ECHO OFF because %!first!% is returned as empty.
How can I print "Hey"
Updated and Clarified:
Here is my full code with comment of what i am trying to do
#ECHO OFF
setlocal EnableDelayedExpansion
set RESULT=TRUE
set INPUT[0]=+NAME=RESULT; VARB=Second; VARC=Second; VARD=Second; VARE=Second; VARF=Second; VARG=Second;
set length=1
set i=0
:loop
if %i% equ %length% goto :eof
for /f "usebackq delims=+ tokens=2" %%j in (`set INPUT[%i%]`) do (
set y=%%j
FOR /f "tokens=1-7 delims=; " %%a IN ("!y!") DO (
set aaa=%%a
set testVar=!aaa:~5!
REM basically testVar resolves to RESULT
echo !!testVar!!
REM Above echo prints "RESULT"
echo %!!testVar!!%
REM Above echo prints "ECHO is off."
)
)
set /a i=%i%+1
goto loop
Instead of ECHO is off. i am trying to output TRUE
#ECHO OFF
setlocal EnableDelayedExpansion
set RESULT=TRUE
set INPUT[0]=+NAME=RESULT; VARB=Second; VARC=Second; VARD=Second; VARE=Second; VARF=Second; VARG=Second;
set length=1
set i=0
:loop
if %i% equ %length% goto :eof
for /f "usebackq delims=+ tokens=2" %%j in (`set INPUT[%i%]`) do (
CALL :sub %%j
)
set /a i=%i%+1
goto loop
GOTO :EOF
:sub
SET "namepart="
FOR %%a IN (%*) DO IF DEFINED namepart (
SET "Valuepart=!%%a!"
ECHO !namepart! is !valuepart!
SET "namepart="
) ELSE (
SET "namepart=%%a"
)
GOTO :eof
It would help if you would explain what you intend to do rather than set up an inquest to determine what you want to do by examining how you have failed to do whatever it is.

is there any method to do same function as for loop without actually using the forloop?

Sample for loop is given below. How to achieve same function without using for loop.
for /l %x in (1, 1, 100) do echo %x
:loop
set /a count+=1
echo %count%
if %count% neq 100 goto:loop
set /a a=1
:label
echo %a%
set /a a+=1
if %a%' EQU 100' (goto :outOfLoop)
goto :label
:outOfLoop
echo done!

Resources