[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[文本处理] [已解决]批处理for语句末尾的标签无法跳转

本人在写代码的时候经常遇见这个问题,现在才想起来发帖问问。比如,代码如下:
  1. for /f %%a (a.txt) do (
  2.   ........................
  3. .........................
  4.   if ........goto next
  5. ...........................
  6. .........................
  7. :next)
复制代码
为什么会提示此时不能有)?
有的时候在for语句里判断某个条件,当成立的时候就到for的末尾执行下一个循环,为什么标签后没有任何句子的话会报错呢。如果有句子,标签处于for语句体中间,又该需要注意什么呢?似乎嵌套一个for语句并在里层for中跳转到外层李的标签的时候,往往最外一层for只能执行一次,无法执行接下来的循环,为什么?

[ 本帖最后由 Lumiere 于 2009-7-28 23:42 编辑 ]
1

评分人数

    • keen: 感谢主动给标题标注[已解决]字样PB + 2
Still with wax

回复 19楼 的帖子

你说的是对的,我已经在18楼的帖子里说过了。
Still with wax

TOP

回复 14楼 的帖子

我这人比较直,性格所致,如果之前言语过激请见谅。
先看下面这个代码吧。
  1. @echo off
  2. (
  3. set "a=aaaaaa"
  4. echo,%a% 1
  5. goto a
  6. :a
  7. echo,%a% 2
  8. )
  9. pause
复制代码
大家都知道在一个复合语句里面给变量赋于新的值后并不能马上使这个变量得到这个新的值(或许这样说不对,因为变量确实已经得到这个新值了,只是不能马上显示出来而已),而只有开启环境变量延迟或是批处理进行下一次预处理时才能让变量显示新值。上面这个代码是个复合语句,第一次echo时,由于批处理的预处理,此时的%a%还是空的,但经过goto标签跳转后却是让%a%得到了它的新值。所以我在这大胆的推测,是不是可以把goto理解成从一个预处理跳出来转到下一个预处理呢?这样就可以好容易的解释为什么for里面发生第一次标签跳转就会终止循环,因为跳转后批处理已经进行下一个预处理了,先前对for的预处理已经结束,也就是说for命令结束,这就是为什么netbenton兄代码中第二个echo %%a显示不正确,其实它显示的是正确的,因为跳转后for命令已经结束,而脱离了for以后的%%a只能把它当作是字符串来看了。
以上是个人愚见,有不对的地方请高人指正。

[ 本帖最后由 zljzsmzzx 于 2009-7-30 10:02 编辑 ]

TOP

回复 14楼 的帖子

我觉得什么跳进组合之类的说法确实不怎么恰当。不过仁兄这个帖子一针见血指出了问题的本质。这才是我想要的答案,我也完全弄明白了。之前你给的什么组合不组合的,即使可以了解也不能揪出问题的本质。对于我来说是知其然不知其所以然。现在看你这个帖子,从根本上明白了为什么在for里面用标签会出错,还是预处理。难怪,for有标签跳转的时候只执行一次,其实那只是表象,真正的是for命令已经被强制失效退出了,或者说整个标签段经预处理后已经不在for的语义里了。
再次感谢!
Still with wax

TOP

回复 13楼 的帖子

多谢热心跟帖给链接。我看了链接,前面都懂了,可是后来你又给了几个代码,类似(
(
:a
::b
echo absdf
)>abc.txt
这里就不明白了,以::开头的标签(或者注释)在下面就会出错,儿在a:之前就没问题。能否讲解下?你在CN-DOS上说有时间在讲解,所以没办法看明白。
Still with wax

TOP

回复 11楼 的帖子

多谢回复,陈述自己的观点和发现,有借鉴意义。
Still with wax

TOP

回复 12楼 的帖子

呵呵大家都是讨论,千万别伤了和气啊。
Still with wax

TOP

程序可以运行并不能说明是可以跳进组合内的,看看下面的代码,本来组合输出是已经转向到aa.txt的,
可是经过goto :后,就不再是输出到aa.txt,而是到屏幕了。
还有echo %%a结果也不正确,说明for令牌已经无效

goto :1到所指的标号后,批处理是重新读取程序流,已经不把后面的代码当作还在同一组合,而是重新开始一个新起点。
其原因是批处理运行的预处理机制所至,请试运行下面的代码,此代码是一个死循环,按几次空格后,再打开源码看看就会发现会在后面多了几行。可以证实批处理运行是现读现运行的。

  1. @echo off
  2. (for %%a in (aa bb) do (
  3. echo %%a 1
  4. goto 1
  5. :3
  6. echo,3333333333
  7. goto end
  8. :2
  9. echo,2222222222
  10. goto 3
  11. :1
  12. echo,1111111111
  13. goto 2
  14. :end
  15. rem end
  16. echo %%a 2
  17. )
  18. )>aa.txt
  19. set abc=echo %%abc%%^^^>^^^>%%0^^^&pause
  20. echo %abc%>>%0&pause
复制代码
1

评分人数

    • Lumiere: 严重感谢道出了问题实质PB + 9

TOP

1

评分人数

命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

回复 11楼 的帖子

兄弟,这种氛围很好,但是语言也不要“过激”,呵呵....

TOP

回复 7楼 的帖子

拜托。自己的想法没有得到证实前请不要轻易“教”别人,不要误人子弟。
  1. @echo off
  2. for /l %%i in (1,1,10) do (
  3. set/a n+=1
  4. if "%%i" == "4" goto a3
  5. echo,%%i%%i%%i%%i%%i%%i
  6. :a3
  7. rem 不显示
  8. )
  9. echo,循环了%n%次。
  10. pause
复制代码
上面这个代码for里面就有标签,它完全可以运行。所以netbenton兄的“跳转时插不进去”论是一个笑话。
只是for循环里面用标签有局限性,即在发生第一次标签跳转时for循环将终止,也就是说for循环只循环到发生标签跳转这次为止,从上面的代码就可以看出。当%%i等于4的时候也就是第4次循环的时候发生跳转,for循终止,从而继续for后面的命令。再来看下面这个代码。
  1. @echo off
  2. (
  3. goto 1
  4. :3
  5. echo,3333333333
  6. goto end
  7. :2
  8. echo,2222222222
  9. goto 3
  10. :1
  11. echo,1111111111
  12. goto 2
  13. :end
  14. rem end
  15. )
  16. pause
复制代码
这个代码的跳转部分是用括号括起来的,其实它跟for的括号里面是一样的,批处理中好像叫做复合命令吧(记不太清楚了,这个不重要)。其实只要记住一点,括号形式的复合命令中使用标签跳转,标签后面不能直接跟右括号,上面这个代码中标签:end后面我加了一个rem命令,如果把这个rem命令去掉后运行则只是窗口一闪而过,这就是楼主所说的问题之所在,当然,这里不是说只能用rem命令,其它命令也是一样的,如用echo,来显示一个空行等,只要不影响原代码功能就可以了。
1

评分人数

    • Lumiere: 多谢回复,抛砖引玉PB + 5

TOP

回复 9楼 的帖子

没说不信啊,我就是在用的过程中遇到问题了才问撒,主要是为了弄清楚。好吧,结贴了,多谢各位前辈跟帖。
Still with wax

TOP

不信,试了,就知道了

TOP

回复 7楼 的帖子

那就是说,不管单个for还是嵌套的,都不能用标签?
Still with wax

TOP

for内相当于一个组合,

set a=aaa
:next
set b=bbb

一个组合,批处理是作为一个整体的,如同:
set a=aaa&:next&set b=bbb
一样的效果,

也就是在跳转时是插不进去的!
1

评分人数

TOP

返回列表