标题: [文本处理] [已解决]批处理for语句末尾的标签无法跳转 [打印本页]
作者: Lumiere 时间: 2009-7-27 17:19 标题: [已解决]批处理for语句末尾的标签无法跳转
本人在写代码的时候经常遇见这个问题,现在才想起来发帖问问。比如,代码如下:- for /f %%a (a.txt) do (
- ........................
- .........................
- if ........goto next
- ...........................
- .........................
- :next)
复制代码
为什么会提示此时不能有)?
有的时候在for语句里判断某个条件,当成立的时候就到for的末尾执行下一个循环,为什么标签后没有任何句子的话会报错呢。如果有句子,标签处于for语句体中间,又该需要注意什么呢?似乎嵌套一个for语句并在里层for中跳转到外层李的标签的时候,往往最外一层for只能执行一次,无法执行接下来的循环,为什么?
[ 本帖最后由 Lumiere 于 2009-7-28 23:42 编辑 ]
作者: Batcher 时间: 2009-7-27 17:50
别把标签放在for循环内部
作者: Lumiere 时间: 2009-7-27 21:21 标题: 回复 2楼 的帖子
管理员能给我解释一下原因么,这样的话帖子结了也难看吧?呵呵
作者: Lumiere 时间: 2009-7-28 08:45
自顶,希望论坛的达人们早日看到并给一个详细的解答,多谢。
作者: slovent 时间: 2009-7-28 09:11
是不是if条件成立后直接运行:next后面的)了?
作者: Lumiere 时间: 2009-7-28 09:42 标题: 回复 5楼 的帖子
标签:next是在for循环体内,而且一开始如果将)作为标签的一部分的话,for的解释会出错,直接退出的,不应该是那种现象。标签应该就是一个标示性的东西,不都说相当于rem或者::么?
作者: netbenton 时间: 2009-7-28 13:20
for内相当于一个组合,
(
set a=aaa
:next
set b=bbb
)
一个组合,批处理是作为一个整体的,如同:
set a=aaa&:next&set b=bbb
一样的效果,
也就是在跳转时是插不进去的!
作者: Lumiere 时间: 2009-7-28 14:17 标题: 回复 7楼 的帖子
那就是说,不管单个for还是嵌套的,都不能用标签?
作者: netbenton 时间: 2009-7-28 19:01
不信,试了,就知道了
作者: Lumiere 时间: 2009-7-28 23:26 标题: 回复 9楼 的帖子
没说不信啊,我就是在用的过程中遇到问题了才问撒,主要是为了弄清楚。好吧,结贴了,多谢各位前辈跟帖。
作者: zljzsmzzx 时间: 2009-7-29 01:20 标题: 回复 7楼 的帖子
拜托。自己的想法没有得到证实前请不要轻易“教”别人,不要误人子弟。- @echo off
- for /l %%i in (1,1,10) do (
- set/a n+=1
- if "%%i" == "4" goto a3
- echo,%%i%%i%%i%%i%%i%%i
- :a3
- rem 不显示
- )
- echo,循环了%n%次。
- pause
复制代码
上面这个代码for里面就有标签,它完全可以运行。所以netbenton兄的“跳转时插不进去”论是一个笑话。
只是for循环里面用标签有局限性,即在发生第一次标签跳转时for循环将终止,也就是说for循环只循环到发生标签跳转这次为止,从上面的代码就可以看出。当%%i等于4的时候也就是第4次循环的时候发生跳转,for循终止,从而继续for后面的命令。再来看下面这个代码。- @echo off
- (
- goto 1
- :3
- echo,3333333333
- goto end
- :2
- echo,2222222222
- goto 3
- :1
- echo,1111111111
- goto 2
- :end
- rem end
- )
- pause
复制代码
这个代码的跳转部分是用括号括起来的,其实它跟for的括号里面是一样的,批处理中好像叫做复合命令吧(记不太清楚了,这个不重要)。其实只要记住一点,括号形式的复合命令中使用标签跳转,标签后面不能直接跟右括号,上面这个代码中标签:end后面我加了一个rem命令,如果把这个rem命令去掉后运行则只是窗口一闪而过,这就是楼主所说的问题之所在,当然,这里不是说只能用rem命令,其它命令也是一样的,如用echo,来显示一个空行等,只要不影响原代码功能就可以了。
作者: lxzzr 时间: 2009-7-29 14:02 标题: 回复 11楼 的帖子
兄弟,这种氛围很好,但是语言也不要“过激”,呵呵....
作者: zqz0012005 时间: 2009-7-29 17:57
此问题以前讨论过
http://bbs.verybat.org/viewthread.php?tid=9863
作者: netbenton 时间: 2009-7-29 19:41
程序可以运行并不能说明是可以跳进组合内的,看看下面的代码,本来组合输出是已经转向到aa.txt的,
可是经过goto :后,就不再是输出到aa.txt,而是到屏幕了。
还有echo %%a结果也不正确,说明for令牌已经无效
goto :1到所指的标号后,批处理是重新读取程序流,已经不把后面的代码当作还在同一组合,而是重新开始一个新起点。
其原因是批处理运行的预处理机制所至,请试运行下面的代码,此代码是一个死循环,按几次空格后,再打开源码看看就会发现会在后面多了几行。可以证实批处理运行是现读现运行的。
-
- @echo off
- (for %%a in (aa bb) do (
- echo %%a 1
- goto 1
- :3
- echo,3333333333
- goto end
- :2
- echo,2222222222
- goto 3
- :1
- echo,1111111111
- goto 2
-
- :end
- rem end
- echo %%a 2
- )
- )>aa.txt
- set abc=echo %%abc%%^^^>^^^>%%0^^^&pause
- echo %abc%>>%0&pause
-
复制代码
作者: Lumiere 时间: 2009-7-29 23:14 标题: 回复 12楼 的帖子
呵呵大家都是讨论,千万别伤了和气啊。
作者: Lumiere 时间: 2009-7-29 23:16 标题: 回复 11楼 的帖子
多谢回复,陈述自己的观点和发现,有借鉴意义。
作者: Lumiere 时间: 2009-7-29 23:19 标题: 回复 13楼 的帖子
多谢热心跟帖给链接。我看了链接,前面都懂了,可是后来你又给了几个代码,类似(
(
:a
::b
echo absdf
)>abc.txt
这里就不明白了,以::开头的标签(或者注释)在下面就会出错,儿在a:之前就没问题。能否讲解下?你在CN-DOS上说有时间在讲解,所以没办法看明白。
作者: Lumiere 时间: 2009-7-29 23:27 标题: 回复 14楼 的帖子
我觉得什么跳进组合之类的说法确实不怎么恰当。不过仁兄这个帖子一针见血指出了问题的本质。这才是我想要的答案,我也完全弄明白了。之前你给的什么组合不组合的,即使可以了解也不能揪出问题的本质。对于我来说是知其然不知其所以然。现在看你这个帖子,从根本上明白了为什么在for里面用标签会出错,还是预处理。难怪,for有标签跳转的时候只执行一次,其实那只是表象,真正的是for命令已经被强制失效退出了,或者说整个标签段经预处理后已经不在for的语义里了。
再次感谢!
作者: zljzsmzzx 时间: 2009-7-30 09:58 标题: 回复 14楼 的帖子
我这人比较直,性格所致,如果之前言语过激请见谅。
先看下面这个代码吧。- @echo off
- (
- set "a=aaaaaa"
- echo,%a% 1
- goto a
- :a
- echo,%a% 2
- )
- pause
复制代码
大家都知道在一个复合语句里面给变量赋于新的值后并不能马上使这个变量得到这个新的值(或许这样说不对,因为变量确实已经得到这个新值了,只是不能马上显示出来而已),而只有开启环境变量延迟或是批处理进行下一次预处理时才能让变量显示新值。上面这个代码是个复合语句,第一次echo时,由于批处理的预处理,此时的%a%还是空的,但经过goto标签跳转后却是让%a%得到了它的新值。所以我在这大胆的推测,是不是可以把goto理解成从一个预处理跳出来转到下一个预处理呢?这样就可以好容易的解释为什么for里面发生第一次标签跳转就会终止循环,因为跳转后批处理已经进行下一个预处理了,先前对for的预处理已经结束,也就是说for命令结束,这就是为什么netbenton兄代码中第二个echo %%a显示不正确,其实它显示的是正确的,因为跳转后for命令已经结束,而脱离了for以后的%%a只能把它当作是字符串来看了。
以上是个人愚见,有不对的地方请高人指正。
[ 本帖最后由 zljzsmzzx 于 2009-7-30 10:02 编辑 ]
作者: Lumiere 时间: 2009-7-30 12:05 标题: 回复 19楼 的帖子
你说的是对的,我已经在18楼的帖子里说过了。
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |