标题: [其他] [已解决]批处理复合语句中是否能使用跳转语句? [打印本页]
作者: summerflower 时间: 2010-2-18 16:33 标题: [已解决]批处理复合语句中是否能使用跳转语句?
复合语句中能用跳转语句吗?我发现复合语句中用跳转语句,它就乱跳,不知道跳到哪里去了
请大家看看下面的代码- @echo off
- setlocal enabledelayedexpansion
- for /l %%a in (1,1,3) do (
- echo 第%%a次
- set str=
- set /p str=请输入:
- if defined str (
- :loopStr
- set strChar=!str:~0,1!
- set str=!str:~1!
- if defined str (
- goto loopStr
- ) else (
- goto endLoopStr
- )
- :endLoopStr
- echo .>nul
- ) else (
- echo ============================
- )
- )
复制代码
如果我第一次输入abc
那么执行结果应该是不输出任何结果,并进行第2、3次循环
但事实上我输入abc
执行结果中竟然输出了============================,并且停止了循环
[ 本帖最后由 summerflower 于 2010-2-24 18:16 编辑 ]
作者: hfg1977 时间: 2010-2-18 16:41
复合语句有很多种的呀, 都可以使用跳转语句.
但是使用的结果会有差异, 要看是否需要返回等等.
乱跳的情况没遇到过 -.- 你说说你情况 一起学习啦!
作者: Seter 时间: 2010-2-18 21:34
用是肯定能用的,问题在于怎么用..
作者: summerflower 时间: 2010-2-19 10:38
- @echo off
- setlocal enabledelayedexpansion
- for /l %%a in (1,1,3) do (
- echo 第%%a次
- set str=
- set /p str=请输入:
- if defined str (
- :loopStr
- set strChar=!str:~0,1!
- set str=!str:~1!
- if defined str (
- goto loopStr
- ) else (
- goto endLoopStr
- )
- :endLoopStr
- echo .>nul
- ) else (
- echo ============================
- )
- )
复制代码
如果我第一次输入abc
那么执行结果应该是不输出任何结果,并进行第2、3次循环
但事实上我输入abc
执行结果中竟然输出了============================,并且停止了循环
大家看看仔细看看这段程序吧
作者: Seter 时间: 2010-2-19 12:24
for中的goto会直接跳出循环,只能用call的...
作者: Seter 时间: 2010-2-19 12:26
你要做啥 = =?
作者: summerflower 时间: 2010-2-19 14:22
是这样的,我在变量dst中存储目标目录(目标目录只有一个),在变量src中存放源文件或源文件夹(源文件或文件夹有多个,用分号隔开)
处理过程:
如果源文件或文件夹的数目大于等于2(
循环分析出每一个源文件或文件夹(
如果源是文件夹(
在目标文件夹中建立子目录
将源文件夹中的内容拷贝到新建立的子目录中
) else (
直接将源文件拷贝到目标文件夹
)
)
) else (
直接将源文件或文件夹里的内容拷贝到目标文件夹
)
我写的思路能看懂吗?
作者: summerflower 时间: 2010-2-19 16:19
复制代码
1.txt的内容
- d:\mydocument\dos练习\测试
- d:\mydocument\dos练习\临时笔记
- d:\mydocument\dos练习\1.bat
复制代码
[ 本帖最后由 summerflower 于 2010-2-19 16:20 编辑 ]
作者: Seter 时间: 2010-2-20 09:02
我怎么完全看不懂吖...
作者: summerflower 时间: 2010-2-20 13:45
看不懂就算了吧,帮我看看第一段代码的问题如何解决
我把goto换成了call
结果call的行为跟goto是一样的
作者: Seter 时间: 2010-2-22 10:34
换成了call。您真聪明吖。
您。语言表达能力比我还差。
劝您。去论坛搜索一下。
作者: terse 时间: 2010-2-22 11:23
这样简单点行不?- @echo off&setlocal enabledelayedexpansion
- for /f "delims=" %%a in (1.txt) do (
- if defined dst (
- if exist "%%a\" (
- xcopy "%%a" /Y /H /R "!dst!\%%~nxa" >nul 2>nul
- ) else copy "%%a" "!dst!"
- ) else set "dst=%%a"
- )
- )
- pause
复制代码
作者: Seter 时间: 2010-2-22 11:30
terse大大真是助人为乐 =v=
还有terse大大语文满分的吧 =v= 帮我解释一下LZ的意思
作者: Batcher 时间: 2010-2-22 12:27 标题: 回复 7楼 的帖子
为了方便他人查看,能否把问题描述和代码全部更新到顶楼?
作者: summerflower 时间: 2010-2-23 14:34
非常感谢terse,你的代码可行
只是想问一下xcopy "%%a" /Y /H /R "!dst!\%%~nxa" >nul 2>nul这条语句为什么还要加上2>nul呢?
也谢谢Secter,其实我要实现的功能,简单的说,就是把源文件或文件夹拷贝到目标目录中去
作者: summerflower 时间: 2010-2-23 14:36
还有,我想知道的是,如果在迫不得已的情况下,我必须在复合语句中使用跳转,那么上面乱跳的情况还是会出现
请问各位高手怎么解决?
作者: namejm 时间: 2010-2-23 15:24
实际上,这个代码并没有乱跳,而是遵循了cmd语句执行的基本规则:
1、for语句中,in……do之间括号中的元素个数决定了do之后括号内所有语句的执行次数,只有当do后所有语句都执行完毕之后,才跳出for循环,执行for语句的下一条语句;
2、goto语句是跳转语句,决定了流程的走向,当它跳转到指定标签后,就自顶向下,逐一执行该标签之后的所有语句,直到文件结尾,除非其间碰到下一条跳转语句才改变这个流程方向。
3、goto循环的优先级高于for循环,也就是说,如果在for语句内部有goto流程跳转语句,将遵循goto的跳转流程,而不必等待for内部循环是否执行完毕。
根据这3条规则,再来分析顶楼的代码就十分好理解了(为了方便演示整个过程,请在最后添加暂停语句pause。):
1、当输入abc的时候,在for语句内部碰到了第一条if语句,判断的结果是str被赋值了,所以,执行 :loopstr 标签段。需要注意的是,:loopstr标签段的作用范围是 :loopstr 和 :endloopstr 之间的语句。在 :loopstr 标签段中,str的值逐次被去掉第一位字符,最终得到空值,结果, :loopstr 标签段循环完之后,就跳转到 :endloopstr 标签段。:endloopstr 标签段的作用范围是作用至文件尾,所以,会执行其后的5行代码,结果,就在屏幕上显示了双横线。回过头来看,在str被赋值的时候,这条for语句是被分成了三大块来执行的:第1块是整个for语句,无需多说;第2块是:loopstr标签段,第3块是 :endloopstr 标签段。由于goto语句的跳转,for语句就被割裂成这3大块来执行,与call调用了一段子程序之后会回过头来执行它的下一句大不一样,goto语句是跳出去之后就不回头的(除非另一条跳转语句又让它跳回来),所以,当str被赋值的时候,for语句不会在内部执行3次do后的语句,而是在第1次执行的时候,就用goto语句跳出了for循环的;
2、当str没有被赋值的时候,for语句内部do后的语句块,第一条if语句没有执行else之前的语句,而是执行了else之后的语句,所以,第1次会显示双横线;因为没有goto语句跳转,for语句继续在内部循环,再次提示你输入,结果会重复第1条或本条的过程,如此循环往复,当每次都没有输入任何字符的时候,for语句将在屏幕上显示3次双横线。换而言之,for把3次内部循环完整地执行了。
作者: 基拉freedom 时间: 2010-2-23 19:14
) else (
goto endLoopStr
)
:endLoopStr
不是纯属多余吗?
作者: bat_521 时间: 2010-9-20 23:39 标题: 回复 17楼 的帖子
namejm 久闻大名,怪不得youxi01站长把 站长的位置交与你托管.你确实水平大大地高.从你对语句的分析和讲解,可以看出你的水平厉害,表达能力特别好,让人一看就懂.批处理之家让你来管,绝对可靠
!
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |