无忧启动论坛

标题: for循环内如何endlocal&set %1= [打印本页]

作者: 2198114498    时间: 2022-6-14 22:07
标题: for循环内如何endlocal&set %1=
本帖最后由 2198114498 于 2022-6-14 22:08 编辑

以下是我自己测试的代码,Test2和Test3均提示错误,
但我的需求是最外层不使用setlocal enabledelayedexpansion,所以不能用Test4。
有办法让endlocal&set %1=在for循环内成功吗?


  1. @echo off
  2. cd /d %~dp0

  3. call :#Test t 11
  4. echo %t%

  5. call :#Test2 t 12
  6. echo %t%

  7. call :#Test3 t 13
  8. echo %t%

  9. setlocal enabledelayedexpansion
  10. call :#Test4 t 14
  11. echo %t%

  12. pause
  13. goto :eof

  14. :#Test
  15. setlocal enabledelayedexpansion
  16. for /f "delims=" %%a in ("%2") do (
  17.         set d2=%%a000
  18.         goto :@1
  19. )
  20. goto :eof
  21. :@1
  22. endlocal &set /a %1=1%d2:~0,3%-1000
  23. goto :eof

  24. :#Test2
  25. setlocal enabledelayedexpansion
  26. for /f "delims=" %%a in ("%2") do (
  27.         set d2=%%a000
  28.         endlocal &set /a %1=1%d2:~0,3%-1000
  29.         goto :eof
  30. )
  31. goto :eof

  32. :#Test3
  33. setlocal enabledelayedexpansion
  34. for /f "delims=" %%a in ("%2") do (
  35.         set d2=%%a000
  36.         endlocal &set /a %1=1!d2:~0,3!-1000
  37.         goto :eof
  38. )
  39. goto :eof

  40. :#Test4
  41. setlocal enabledelayedexpansion
  42. for /f "delims=" %%a in ("%2") do (
  43.         endlocal &set d2=%%a000&set /a %1=1!d2:~0,3!-1000
  44.         goto :eof
  45. )
  46. goto :eof
复制代码





作者: 2010techon    时间: 2022-6-15 02:49
本帖最后由 2010techon 于 2022-6-15 02:51 编辑

你这个用法除了第一条用的合理,后面的用法不对。。。
  1. endlocal &set /a %1=1%d2:~0,3%-1000
复制代码
for是一个语句块,命令行对此有些特殊处理,比如你在里面用endlocal就会立即生效,后面就没法使用d2这个变量了。。。你可以这么用:
  1. :#Test2
  2. setlocal enabledelayedexpansion
  3. for /f "delims=" %%a in ("%2") do (
  4.         set d2=%%a000
  5.         for %%z in (!d2!) do endlocal&echo,d2==%%z&set /a %1=1%%z-10000
  6.    rem 或者
  7.    rem for /f %%z in ('call echo,%%d2%%') do endlocal&echo,d2==%%z
  8.    rem 但是这时你没法使用变量截取功能
  9.         goto :eof
  10. )
  11. goto :eof
复制代码

你需要仔细理解一下 setlocal 和 endlocal 的功能,setlocal 设置一个独立的变量空间
在此之后设置的变量在下一次 endlocal 之前可以使用,超出范围就不能用了。
独立语句行上的 endlocal &set。。。是个特殊情况。


作者: 2198114498    时间: 2022-6-15 09:04
2010techon 发表于 2022-6-15 02:49
你这个用法除了第一条用的合理,后面的用法不对。。。
for是一个语句块,命令行对此有些特殊处理,比如你 ...

谢谢,基本上有了新需要都边学边测试,对原理理解不透。
学习了,看来还是goto跳出更直接也好理解。
作者: 2010techon    时间: 2022-6-15 13:08
2198114498 发表于 2022-6-15 09:04
谢谢,基本上有了新需要都边学边测试,对原理理解不透。
学习了,看来还是goto跳出更直接也好理解。
  1. :#Test
  2. setlocal enabledelayedexpansion
  3. for /f "delims=" %%a in ("%2") do (
  4.         set d2=%%a000
  5.         goto :@1
  6. )
  7. goto :eof
  8. :@1
  9. endlocal &set /a %1=1%d2:~0,3%-1000
  10. goto :eof
复制代码
你这个部分逻辑上可能会有问题:当 %2 为空时 for /f "delims=" %%a in ("%2") do。。。这个for不会执行
所以会直接执行 goto :eof 返回了,但是之前你有setlocal,这时setlocal和endlocal不成对了。
当然,如果你确定 %2不会为空,那么for里面的goto :@1 就没有意义,可以和后面的 goto :eof 还有 :@1一起删掉:
  1. :#Test
  2. setlocal enabledelayedexpansion
  3. for /f "delims=" %%a in ("%2") do (
  4.         set d2=%%a000
  5. )
  6. endlocal &set /a %1=1%d2:~0,3%-1000
  7. rem 这里setlocal和endlocal就不会有问题了,但是如果%2为空,set /a %1=1%d2:~0,3%-1000 将出现错误结果
  8. goto :eof
复制代码

更好的用法是这样:
  1. :#Test
  2. for /f "delims=" %%a in ("%2") do (
  3.         setlocal enabledelayedexpansion
  4.         set d2=%%a000
  5. )
  6. if defined d2 (endlocal &set /a %1=1%d2:~0,3%-1000)
  7. goto :eof
复制代码


作者: 2198114498    时间: 2022-6-15 17:37
2010techon 发表于 2022-6-15 13:08
你这个部分逻辑上可能会有问题:当 %2 为空时 for /f "delims=" %%a in ("%2") do。。。这个for不会执行
...

谢谢提醒,测试代码没有细节,实际会有很多分支,包括for未进入循环。
作者: cxincn    时间: 2022-6-19 22:52
学习学习
作者: nowayer    时间: 2023-11-7 02:10
提示: 作者被禁止或删除 内容自动屏蔽
作者: dos时代菜鸟    时间: 2023-11-7 08:18
for 内 用 call
call setlocal enabledelayedexpansion




欢迎光临 无忧启动论坛 (http://wuyou.net./) Powered by Discuz! X3.3