Page 1 of 3
Is it possible to break loop?
Posted: 25 Jun 2012 04:01
by doscode
I tried to break loop. Now it seems it does not work.
The script is long, so just shorted:
Code: Select all
FOR /F "tokens=1-20 delims=<>" %%A IN ('somefile.txt') DO (
FOR %%Z in ( "%%A", "%%B", "%%C", "%%D", "%%E", "%%F", "%%G", "%%H", "%%I", "%%J", "%%K", "%%L", "%%M", "%%N", "%%O", "%%P", "%%Q") DO (
if !break! EQU 1 (
echo this is error
pause
)
SET /A cnt=!cnt!+1
if !cnt! LSS 4 (
SET IP=!IP!!legalNumber!.
) else (
SET IP=!IP!!legalNumber!
SET /A cnt=0
SET /A break=1
break;
)
echo /!cnt!/!IP!
REM Endof For %%Z
)
)
As I added
Code: Select all
if !break! EQU 1 (
echo this is error
pause
)
I have found that the loop continues even it was breaked. If I would use exit /b instead, the script is finished.
Re: Is it possible to break loop?
Posted: 25 Jun 2012 05:48
by jeb
Did you read the help for
break;
Sometimes it's useful to read the help or ask google
Re: Is it possible to break loop?
Posted: 25 Jun 2012 06:06
by doscode
jeb wrote::roll: Did you read the help for
break;
Sometimes it's useful to read the help or ask google
Yes I did
Break /? Is very curt
I think I have two options. Either to use inner condition (cycles would not be skipped) or to move the inner code to separated subroutine and to call this subroutine from the main loop. Then I can use exit /b
Disadvantages of subroutine, I would need to define many arguments (about 40), and it could make the code longer and less clear.
Adding inner condition seems to me as the simplest way. Disadvantage is that the structure get a little more complicated when I will add another condition.
Subroutine requires reading array of arguments which can consume some (short) time. But the inner condition doesn't break the loop at all. What is faster?
Re: Is it possible to break loop?
Posted: 25 Jun 2012 06:52
by jeb
doscode wrote: Did you read the help for
...
doscode wrote:Break /? Is very curt
Then you should recognized that the help of break /? explained that the command has no effect on a windows plattform and is only for compatibility of old DOS software.
I asked google:
how to break a batch loopAnd it shows the answer:
Use goto :label to break a for-loop
Code: Select all
For %%A in (1 2 3) do (
echo %%A
goto :myBreak
)
:myBreak
Re: Is it possible to break loop?
Posted: 25 Jun 2012 08:11
by doscode
jeb wrote:Use goto :label to break a for-loop
I've seen the similar:
http://stackoverflow.com/questions/4710 ... tch-script"One remark, breaking of FOR /L loops does not work as expected, the for-loop always count to the end, but if you break it, the execution of the inner code is stopped, but it could be really slow."Code: Select all
@echo off
SETLOCAL EnableDelayedExpansion
for %%a in (a b c) DO (
echo Outer loop %%a
call :inner %%a
)
goto :eof
:inner
for %%b in (U V W X Y Z) DO (
if %%b==X (
echo break
goto :break
)
echo Inner loop Outer=%1 Inner=%%b
)
:break
goto :eof
But the example was used with subroutine
Re: Is it possible to break loop?
Posted: 25 Jun 2012 09:29
by doscode
I already had tested goto in the inner loop before I started to look for help. It failed to me. So I tried your recommandation, in this way:
FOR /F "tokens=1-20 delims=<>" %%A IN ('somefile.txt') DO (
FOR %%Z in ( "%%A", "%%B", "%%C", "%%D", "%%E", "%%F", "%%G", "%%H", "%%I", "%%J", "%%K", "%%L", "%%M", "%%N", "%%O", "%%P", "%%Q") DO (
if !break! EQU 1 (
echo this is error
pause
)
SET /A cnt=!cnt!+1
if !cnt! LSS 4 (
SET IP=!IP!!legalNumber!.
) else (
SET IP=!IP!!legalNumber!
SET /A cnt=0
SET /A break=1
goto :myBreak
)
echo /!cnt!/!IP!
REM Endof For %%Z
)
:myBreak
REM Next code here
)
And it fails to me with error Incorrect syntax
Why?
Re: Is it possible to break loop?
Posted: 25 Jun 2012 09:46
by Fawers
Another way to break a loop is to have a FOR CALLing a "label function".
Code: Select all
@echo off
for /f "tokens=1,2" %%a in ('dir') do (
call :ToBreakOrNotTobreak "%%a" "%%b"
)
:ToBreakOrNotToBreak
if "%2" == "file(s)" (set /a "files=%1"
) else exit /b
This will call the label for each %%a and %%b.
Another way is to put the entire for loop in a section.
Code: Select all
@echo off
::some code here
call :BreakableLoop
goto :eof
:BreakableLoop
::for loop here (
::some code here
::some other code here
::if CONDITION is MET, then exit /b
::some more code here
)
Re: Is it possible to break loop?
Posted: 25 Jun 2012 09:59
by Squashman
You can't break out of the inner loop with a goto without breaking the outer loop as well and you definitely can't break out of the inner loop with a goto to a label at the end of the outer loop.
Re: Is it possible to break loop?
Posted: 25 Jun 2012 10:12
by doscode
I think I know where the problem is. It is not possible to do this:
REM Outer loop starts...for ... do ( REM Inner loop starts ...
for ... do (
if ... goto :break
):breakREM Endof outer loop:)Because the error is ") not expected".
When I tooks Jebs example, I changed it to the principle of this:
Code: Select all
echo off
For %%D in (1 2 3) do (
For %%A in (1 2 3) do (
echo %%A
goto :myBreak
)
)
:myBreak
Re: Is it possible to break loop?
Posted: 25 Jun 2012 15:11
by Ed Dyreen
Squashman wrote:You can't break out of the inner loop with a goto without breaking the outer loop as well and you definitely can't break out of the inner loop with a goto to a label at the end of the outer loop.
The only thing I use goto for, is to break inner loops without breaking out of the outer subroutine/function.
Code: Select all
@echo off &setlocal enableDelayedExpansion
:main ()
:: (
:break ()
:: (
for /l %%? in (
1,1,3
) do (
echo.main
call :loop1 "()"
goto :break "()"
)
:: )
:break ()
:: )
echo.end &pause &exit /b 0
:loop1 ()
:: (
:break ()
:: (
for /l %%? in (
1,1,3
) do (
echo.loop1
goto :break "()"
)
:: )
:break ()
:: )
exit /b 0
Code: Select all
main
loop1
end
Druk op een toets om door te gaan. . .
Re: Is it possible to break loop?
Posted: 25 Jun 2012 16:23
by dbenham
Logically you might want something like the following: (pseudo code)
Code: Select all
for var1 in (list1) do (
for var2 in (list2) do (
do something with var1 and var2
if var2=EndCondition break out of loop2
)
)
As has been pointed out, you need to use a called subroutine for the inner loop, and you can safely break out of the inner loop and return to the outer loop using GOTO.
But you might fret, the context of the outer loop dissapears while I am in the called subroutine, so I can't access the outer loop variable. No worries...
What hasn't been explained is that the variable from the outer loop is available within the inner loop
Given that we are in a subroutine, a simpler approach to breaking out of the inner loop is to use EXIT /B instead of GOTO :LABEL.
Here is an example that demonstrates both concepts. Note how %%A is initially not available within the subroutine. But while inside the inner loop it "magically" reappears.
Code: Select all
@echo off
for %%A in (1 2 3) do (
echo(
echo inside outer loop: A=%%A
call :innerSub
)
exit /b
:innerSub
echo inside innerSub but before inner loop: A=%%A
for %%B in (a b c e e) do (
echo inside inner loop: A=%%A B=%%B
if %%B==c exit /b
)
exit /b
output:
Code: Select all
inside outer loop: A=1
inside innerSub but before inner loop: A=%A
inside inner loop: A=1 B=a
inside inner loop: A=1 B=b
inside inner loop: A=1 B=c
inside outer loop: A=2
inside innerSub but before inner loop: A=%A
inside inner loop: A=2 B=a
inside inner loop: A=2 B=b
inside inner loop: A=2 B=c
inside outer loop: A=3
inside innerSub but before inner loop: A=%A
inside inner loop: A=3 B=a
inside inner loop: A=3 B=b
inside inner loop: A=3 B=c
Dave Benham
Re: Is it possible to break loop?
Posted: 25 Jun 2012 21:47
by Aacini
You may get an
equivalent behaviour of breaking the inner loop and passing to the next iteration of the outer loop if you enclose the body of inner loop in an IF controled by a break variable:
Code: Select all
@echo off
for %%D in (1 2 3) do (
set break=
for %%A in (1 2 3) do (
if not defined break (
echo D=%%D, A=%%A
if %%A equ 2 set break=TRUE
)
)
)
Antonio
Re: Is it possible to break loop?
Posted: 25 Jun 2012 23:39
by doscode
Aacini wrote:You may get an
equivalent behaviour of breaking the inner loop and passing to the next iteration of the outer loop if you enclose the body of inner loop in an IF controled by a break variable:
Code: Select all
@echo off
for %%D in (1 2 3) do (
set break=
for %%A in (1 2 3) do (
if not defined break (
echo D=%%D, A=%%A
if %%A equ 2 set break=TRUE
)
)
)
Antonio
This is unbelievable. Your code is so simple and it really works. If I remove the condition so it stopped to worked. When I tried to use it in my inner loop, I have this condition and it does not work:
Code: Select all
if !ThisIsLegalNumber! EQU 1 (
REM ECHO THIS IS LEGAL NUMBER
SET legalNumber=!second!
SET /A cnt=!cnt!+1
if !cnt! LSS 4 (
SET IP=!IP!!legalNumber!.
) else (
SET IP=!IP!!legalNumber!
SET /A cnt=0
SET /A Search_IP=0
REM THIS IS FINISH OF THE LOOP
set break=TRUE
)
)
So it cannot be separated in the else branch or with other commands?
If I change it to:
Code: Select all
set break=
if !ThisIsLegalNumber! EQU 1 (
REM ECHO THIS IS LEGAL NUMBER
SET legalNumber=!second!
SET /A cnt=!cnt!+1
if !cnt! LSS 4 (
SET IP=!IP!!legalNumber!.
) else (
SET IP=!IP!!legalNumber!
SET /A cnt=0
SET /A Search_IP=0
REM THIS IS FINISH OF THE LOOP
if !cnt! EQU 4 set break=TRUE
)
echo /!cnt!/!IP!
)
So it still continues in the inner loop. Even the IP address is completed. I have to have some mistake there in the code. Any idea what could be wrong?
Re: Is it possible to break loop?
Posted: 25 Jun 2012 23:49
by Aacini
Code: Select all
set and=if
. . . . .
set break=
rem The inner loop start here...
if !ThisIsLegalNumber! EQU 1 %and% not defined break (
REM ECHO THIS IS LEGAL NUMBER
SET legalNumber=!second!
SET /A cnt=!cnt!+1
if !cnt! LSS 4 (
SET IP=!IP!!legalNumber!.
) else (
SET IP=!IP!!legalNumber!
SET /A cnt=0
SET /A Search_IP=0
REM THIS IS FINISH OF THE LOOP
if !cnt! EQU 4 set break=TRUE
)
echo /!cnt!/!IP!
)
Re: Is it possible to break loop?
Posted: 26 Jun 2012 00:07
by doscode
I don't understand your code, why you write it this way.
if !ThisIsLegalNumber! EQU 1 %and% not defined break
What does it mean? I think that it doesn't solve anything. Will this break the loop or not? Next code there.