0

我已将有问题的代码剥离到有问题的行。为什么第一个回声有效而第二个无效?

setlocal enabledelayedexpansion
set /a r=19
set blocks=MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM

for /L %%a in (-%r%,1,%r%) do (
   set /a w2=r
   :: This works
   set line=!blocks:~0,%r%!
   echo( !line!

   ::This does'nt work
   set line=!blocks:~0,!w2!!   
   echo( !line!
)  
exit /b 

编辑:我一直在尝试,这条线有效:

call set line=%%blocks:~0,!w2!%%

现在的问题是:有人可以向我解释为什么我必须使用电话吗?

4

2 回答 2

1

使用 !delayed 扩展来扩展变量的可能方法!在这篇文章中描述了使用其他变量来表示可能在代码块内发生变化的子字符串位置或长度:

要在 FOR/IF 内的索引更改时获取子字符串的值,请将子字符串用双百分号括起来,并在命令前加上 call。例如:

call set line=%%blocks:~0,!w2!%%

此方法很好地利用了callcommand 允许重新扩展包含在双百分号中的变量这一事实,如该问题的第二个答案中所述:

批处理线解析器:

1) 阶段:%var%...的扩展

6) 阶段:如果命令是 CALL,则再次从阶段 1 开始。

实现上述过程的另一种方法是使用附加的 FOR 命令,通过等效的可替换参数来更改索引的延迟扩展,然后对子字符串使用延迟扩展。此方法比以前的 CALL 运行得更快:

for %%w in (!w2!) do set line=!blocks:~0,%%w!
于 2016-05-29T12:23:49.697 回答
1

r只要值在循环内没有改变,您应该直接使用百分比扩展的变量。

set line=!blocks:~0,%r%!

或者对其他变量使用辅助循环。

 for /F "tokens=*" %%H in ("!w2!") do (
      set line=!blocks:~0,%%H!
   )
于 2016-05-29T12:21:45.143 回答