2

我在 while 循环中有一个 for 循环。我有一个条件来打破 for 循环中的 while。

这是代码:

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
}

我想跳过$nb_lines解析的文件以进一步做其他事情。这里的break,打破了for循环,所以它不起作用。

for 循环可以使 while 循环中断吗?但是中断仅针对 1 行(或更多)行,我想在中断后继续解析文件以进一步处理行

谢谢

4

2 回答 2

3

break命令(以及continue)不执行多级循环退出。IMO,最简单的解决方法重构代码,以便您可以return退出外循环。但是,如果你不能这样做,那么你可以使用类似这样的东西(对于 8.5 及更高版本):

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
}

不是很特别(它只是一个自定义结果5代码;Tcl 保留 0-4,但不理会其他人)但是您需要为自己选择一个值,这样它就不会与程序中的任何其他用途重叠。(大多数情况下可以重做代码,因此它也适用于 8.4 及之前的版本,但在那里重新抛出异常要复杂得多。)

请注意,自定义异常代码是 Tcl 的“深层魔法”部分。如果可以,请改用普通重构。

于 2012-07-17T20:09:07.957 回答
2

也许很明显,但您可以使用一个附加变量 ( go_on) 来中断 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
}
于 2012-07-17T13:39:46.947 回答