问题
I have a for loop in a while loop. I have a condition to break the while in the for loop.
Here is the code :
while {[gets $thefile line] >= 0} {
for {set i 1} {$i<$count_table} {incr i} {
if { [regexp "pattern_$i" $line] } {
for {set break_lines 1} {$break_lines<$nb_lines} {incr break_lines} {
if {[gets $thefile line_$break_lines] < 0} break
}
}
#some other process to do
}
I want to skip $nb_lines
in the file parsed to do other thing further. Here the break, breaks the for loop, so it doesn't work.
Can the for loop make the while loop broken ? But the break is just for 1 (or more) lines, i want to continue to parse the file after the break to process line further
Thanks
回答1:
The break
command (and continue
too) doesn't do multi-level loop exit. IMO, the simplest workaround is to just refactor the code so you can return
to exit the outer loop. However, if you can't do that, then you can use something like this instead (for 8.5 and later):
proc magictrap {code body} {
if {$code <= 4} {error "bad magic code"}; # Lower values reserved for Tcl
if {[catch {uplevel 1 $body} msg opt] == $code} return
return -options $opt $msg
}
proc magicthrow code {return -code $code "doesn't matter what this is"}
while {[gets $thefile line] >= 0} {
magictrap 5 {
for {set i 1} {$i<$count_table} {incr i} {
if { [regexp "pattern_$i" $line] } {
for {set break_lines 1} {$break_lines<$nb_lines} {incr break_lines} {
if {[gets $thefile line_$break_lines] < 0} {magicthrow 5}
}
}
}
}
#some other process to do
}
The 5
isn't very special (it's just a custom result code; Tcl reserves 0–4, but leaves the others alone) but you need to pick a value for yourself so that it doesn't overlap with any other uses in your program. (It is mostly possible to redo the code so it works with 8.4 and before too, but it's quite a bit more complex to rethrow an exception there.)
Be aware that custom exception codes are a “deep magic” part of Tcl. Please use ordinary refactoring instead if you can.
回答2:
Perhaps obvious, but you can use an additional variable (go_on
) to break the while:
while {[gets $thefile line] >= 0} {
set go_on 1
for {set i 1} {$i<$count_table && $go_on} {incr i} {
if { [regexp "pattern_$i" $line] } {
for {set break_lines 1} {$break_lines<$nb_lines && $go_on} {incr break_lines} {
if {[gets $thefile line_$break_lines] < 0} { set go_on 0 }
}
}
}
#some other process to do
}
来源:https://stackoverflow.com/questions/11523432/breaking-parent-loop-in-tcl