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

[文本处理] 按顺序和倒序输出数字的批处理代码错在哪里?

出错的代码:
  1. @echo off
  2. set str=1 2 3 4 5 6 7 8 9
  3. for %%i in (%str%) do (
  4. setlocal ENABLEDELAYEDEXPANSION
  5. set res=%%i!res!
  6. set ser=!ser!%%i
  7. endlocal
  8. )
  9. echo %res% & echo %ser%
  10. pause
复制代码
但是没有 “endlocal” 就可以正确运行了。

楼主的这个例子中 setlocal ENABLEDELAYEDEXPANSION 写在 for 前面就行了,不需要用在循环里
先简单解释下 setlocal 和 endlocal:
  1. setlocal 实现变量本地化的原因是它每次被执行时都会创建一张新的变量表,此后的所有变量操作都在这张新表上进行,上限 32 张表(在 call 中会另行计数),为避免超出这一限制,需要使用 endlocal 来释放由 setlocal 所产生的最新的变量表,表中的变量自然也就随之丢失。
复制代码
再说说为什么许多代码要在循环中用到 setlocal 和 endlocal:
我们在 for 中使用 setlocal 和 endlocal 的目的一般是为了与变量赋值配合,以便在必须使用变量延迟的时候也能输出含有 ! 的字符串,对比下面两个例子:
  1. @echo off&setlocal enabledelayedexpansion
  2. for /f "delims=" %%a in ("^!tmp^!") do echo !date!-%%a
  3. ::这里的 !tmp! 在 echo 的时候被解释为变量 tmp 的值,而我们实际上想输出的是 "!tmp!" 这个含有 ! 的字符串本身,可是由于开启了变量扩展后直接引用 %%a,所以其中的 !tmp! 被解释为变量
  4. pause
复制代码
  1. @echo off
  2. for /f "delims=" %%a in ("^!tmp^!") do (
  3. set str=%%a
  4. setlocal enabledelayedexpansion
  5. echo !date!-!str!
  6. endlocal
  7. )
  8. ::经过 set str=%%a 与 setlocal enabledelayedexpansion,!tmp! 被赋值到变量 str,以便在 echo 的时候以 !str! 的形式避开变量延迟对于 %%a 的解释
  9. pause
复制代码
但是 setlocal 和 endlocal 之间的变量会丢失,解决办法是用 for 将延迟变量 !num! 转换为参数变量 %%a,以便在 endlocal 之后再把 %%a 赋值给 num 变量:
  1. set num=test
  2. setlocal enabledelayedexpansion
  3. set num=1234
  4. rem 如果直接 endlocal,%num% 将还原成 setlocal 之前的最后状态,即 num=test
  5. endlocal&set num=%num%
  6. rem 因为 %num% 是在执行 endlocal 之前就被解释的(若是延迟变量 !num!,则只在命令执行前被解释),所以经过再赋值即可保留 num 变量
  7. echo %num%
复制代码
如果是在复合语句中则没法简单用 endlocal&set num=%num% 解决,此时必须使用变量延迟以保证所得的 num 是即时的,那么应这样:
  1. (set num=test
  2. setlocal enabledelayedexpansion
  3. set num=1234
  4. rem 如果直接 endlocal,%num% 将还原成 setlocal 之前的最后状态,即 num=test
  5. for %%a in (!num!) do endlocal&set num=%%a
  6. rem 经过 for 的中转和再赋值,既保证了 !num! 是执行 for 前刚刚被解释的,又保证 endlocal 之后它的值能够得以保留
  7. )
  8. echo %num%
复制代码
1

评分人数

    • plp626: 楷模会员。。。PB + 10

TOP

返回列表