找回密码
 注册
搜索
[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
查看: 38073|回复: 16

【练习-053】按要求补全变量嵌套中的批处理代码

[复制链接]
发表于 2009-11-20 16:37:18 | 显示全部楼层 |阅读模式
出题目的:
    1、初步了解变量嵌套概念
    2、搞清楚cmd对变量的解析(值的释放)过程
加分原则:
    满分10分
题目如下:
    有一简单的变量嵌套代码如下:
  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=bathome"
  3. ::以下for循环实现的是set "b=a"&set "c=b"&set "d=c"&set "e=d"
  4. for %%a in (ba cb dc ed) do set "str=%%a"&set "!str:~,1!=!str:~1!"
复制代码
请补全代码,要求只用e变量的解析式来输出结果“bathome”,也就是说你知道e变量
以及中间变量的转承过程,但在解析式中不能用到%a% %b% %c% %d%或!a! !b! !c! !d!,只
能用到%e%或!e!。
发表于 2009-11-20 17:08:42 | 显示全部楼层
这么快又发一道题…… 是基础题。
做法1:
set e=!%e%!
set e=!%e%!
set e=!%e%!
echo !%e%!
pause

评分

参与人数 1PB +5 收起 理由
batman + 5 笨方法有时也实用

查看全部评分

 楼主| 发表于 2009-11-21 10:51:52 | 显示全部楼层

回复 2楼 的帖子

就本题而言你这样的做法是正确的,但假如中间有100道转承关系呢?

[ 本帖最后由 batman 于 2009-11-21 10:53 编辑 ]
发表于 2009-11-21 11:10:19 | 显示全部楼层
那就用一个循环来“递推”吧
仍然可能考虑goto 循环,

因为在for中是复合句,%var%总是for之前的结果 ,也许还会考虑进一步for替换!! 吧
这些都是方法
call %%!!%% 的方式,因为大家都说call低效,于是我也开始避开了

[ 本帖最后由 523066680 于 2009-11-21 11:14 编辑 ]

评分

参与人数 1PB +5 收起 理由
batman + 5 yes!

查看全部评分

 楼主| 发表于 2009-11-21 11:38:13 | 显示全部楼层
&&本人认为采用for循环的方式来解析应该是一种替归的方式,

不然当存在大量中间变量和转承关系时,单用for也解决不了。

同时exist上面提到的循环递推的方式和本人提到的for循环替

归方式都是可以忽略中间有多少层变量和转承这个条件的,唯

一只是要设置中止条件而己(变量值为空)。

[ 本帖最后由 batman 于 2009-11-21 11:40 编辑 ]
发表于 2009-11-21 12:11:52 | 显示全部楼层
  1. :again
  2. set e=!%e%!
  3. if  "%e%"=="bathome" ( echo %e%&pause&goto :eof)else goto again
复制代码
不明白用FOR怎么去实现,只能用这种方法了。

[ 本帖最后由 tevktev 于 2009-11-21 20:24 编辑 ]

评分

参与人数 1PB +5 收起 理由
batman + 5 中止条件有误

查看全部评分

 楼主| 发表于 2009-11-21 17:18:27 | 显示全部楼层
大家都想一下怎么用for来实现这一变量解析的过程,

提示:用一个for表达式来代替n个for嵌套表达式,可

参考下面这个代码:
  1. @echo off
  2. set "str=a-b-c-d-e-f-g-h-i-j"
  3. call :lp "%str%"
  4. pause>nul&goto :eof
  5. :lp
  6. for /f "tokens=1* delims=-" %%a in (%1) do (
  7.       if "%%b" neq "" (
  8.          call :lp "%%b"
  9.          ) else (
  10.          echo %%a
  11.       )
  12. )
复制代码

[ 本帖最后由 batman 于 2009-11-21 17:27 编辑 ]
发表于 2009-11-21 17:33:29 | 显示全部楼层
做什么用呢?

俺不懂!
 楼主| 发表于 2009-11-21 17:39:46 | 显示全部楼层

回复 8楼 的帖子

顶楼有出题的目的说明,这是道基础知识类的题,不是要展示你的技巧,而是要考察你的基本概念和思路。
发表于 2009-11-21 17:56:43 | 显示全部楼层
  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=bathome"
  3. ::以下for循环实现的是set "b=a"&set "c=b"&set "d=c"&set "e=d"
  4. for %%a in (ba cb dc ed) do set "str=%%a"&set "!str:~,1!=!str:~1!"
  5. call :lp e
  6. pause&goto :eof
  7. :lp
  8. if defined %~1 (call %0 !%~1!)else echo %~1
复制代码

评分

参与人数 1PB +10 收起 理由
batman + 10 这就是替归模式

查看全部评分

发表于 2009-11-21 19:13:22 | 显示全部楼层
  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=bathome"
  3. ::以下for循环实现的是set "b=a"&set "c=b"&set "d=c"&set "e=d"
  4. for %%a in (ba cb dc ed) do set "str=%%a"&set "!str:~,1!=!str:~1!"

  5. call,call,call,set e=%%%%%%%%%%%%%%%e%%%%%%%%%%%%%%%
  6. call,echo %%%e%%%

  7. pause
复制代码



::虽然 call 效率低 但也想贴出来(针对本题的转承次数)
回去想了想---可以一call到底
call,call,call,call,echo %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%e%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

[ 本帖最后由 vsbat 于 2009-11-22 13:14 编辑 ]

评分

参与人数 1PB +5 收起 理由
batman + 5 call是影响效率,但也不能一棒子打死

查看全部评分

发表于 2009-11-21 20:20:48 | 显示全部楼层

回复 7楼 的帖子

中止有误?
能不能给出修正后的代码。
谢谢

[ 本帖最后由 tevktev 于 2009-11-21 20:27 编辑 ]
 楼主| 发表于 2009-11-21 20:43:31 | 显示全部楼层

回复 12楼 的帖子

if  "%e%"=="bathome" 应该是if "%e%"=="",你不能直接将最后的值写出来,换句话就是你根本不知道最后的值是多少。
发表于 2010-8-1 23:46:35 | 显示全部楼层

累死俺了,数了一晚上呢。。。

  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=bathome"
  3. ::以下for循环实现的是set "b=a"&set "c=b"&set "d=c"&set "e=d"
  4. for %%a in (ba cb dc ed) do set "str=%%a"&set "!str:~,1!=!str:~1!"
  5. call call call call set /p=e=%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%e%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  6. pause
复制代码
发现这样还简洁点,请问各位前辈,还能再简洁不了呢。。。
  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=bathome"
  3. ::以下for循环实现的是set "b=a"&set "c=b"&set "d=c"&set "e=d"
  4. for %%a in (ba cb dc ed) do set "str=%%a"&set "!str:~,1!=!str:~1!"
  5. call call call set /p=e=%%%%%%%%%%%%%%!%e%!%%%%%%%%%%%%%%
  6. pause
复制代码

[ 本帖最后由 fish 于 2010-8-1 23:51 编辑 ]
发表于 2010-8-2 03:33:32 | 显示全部楼层
  1. @echo off&setlocal enabledelayedexpansion
  2. set "a=bathome"
  3. set "b=a"&set "c=b"&set "d=c"&set "e=d"
  4. for %%i in (b c d) do for %%j in ("!%%i!") do set %%i=!%%~j!
  5. echo !%e%!
  6. pause
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|批处理之家 ( 渝ICP备10000708号 )

GMT+8, 2026-3-16 22:18 , Processed in 0.023441 second(s), 9 queries , File On.

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表