Board logo

标题: 一个批处理题目里受到的启发:set /p 输出指定格式文本 [打印本页]

作者: p05401144    时间: 2009-1-13 00:11     标题: 一个批处理题目里受到的启发:set /p 输出指定格式文本

今天在做“输出9*9口诀”时受到了一些启发,现在与广大菜鸟同志们一起分享。
因为学过C语言,所以我在做这个题目时并不感到困难,下面是我做的答案:
@echo off
setlocal enabledelayedexpansion
for /l %%a in (1,1,9) do (for /l %%b in (1,1,9) do (set/a res=%%a*%%b&echo %%a*%%b=!res!))
pause
(说一下,我在做的时候把!res!写成%res%,总是得不到结果,后来查了资料才知道在引用延迟变量时一点要用!!,所以我在这里再啰嗦一次:细节很重要。)
就在我为自己又做出一道题目而窃窃自喜的时候,namejm的答案彻底的让我笑不出来了:
@echo off &setlocal enabledelayedexpansion
for /l %%a in (1 1 9) do (
        for /l %%b in (1 1 %%a) do (
                set/a res=%%a*%%b
                set "res=!res!  " %======此处用来对齐=========%
                set/p=%%ax%%b=!res:~0,2!  <nul
        )
        echo.
)
pause>nul
运行结果如下:
1x1=1  
2x1=2   2x2=4   
3x1=3   3x2=6   3x3=9   
4x1=4   4x2=8   4x3=12  4x4=16  
5x1=5   5x2=10  5x3=15  5x4=20  5x5=25  
6x1=6   6x2=12  6x3=18  6x4=24  6x5=30  6x6=36  
7x1=7   7x2=14  7x3=21  7x4=28  7x5=35  7x6=42  7x7=49  
8x1=8   8x2=16  8x3=24  8x4=32  8x5=40  8x6=48  8x7=56  8x8=64  
9x1=9   9x2=18  9x3=27  9x4=36  9x5=45  9x6=54  9x7=63  9x8=72  9x9=81  
实在是太完美了!!!
在我认真研究了程序后,有了一个发现,他竟然是用set /p来做输出的,实在太有创意了!!!

现在我把我对set/p=%%ax%%b=!res:~0,2!  <nul 的理解分享一下:
set /p 是让用户输入字来符赋予变量的命令,这里并没有变量,所以直接显示后面的内容,但显示完了以后set /p还是会向你要输入(就像地主向农民催租一样),怎么办呢?这时<nul就起作用了
查资料得:
<:重新定向输入,从文本中读入输入命令,而不是从键盘中读入
所以<nul就是禁止输入的意思,就搞定了(解放了,不用交租了)
通过这里我得到一个启发,用 set /p="要显示的内容" <nul 可以代替echo,甚至由于set命令可以进行字符串截取,使它在用来作输出显示时,比echo更强大。
由于水平有限,如果有什么错误,还请老鸟们不吝指正,以免误导新人。

[ 本帖最后由 p05401144 于 2009-1-13 10:31 编辑 ]
作者: wxcute    时间: 2009-1-13 13:03

“就像地主向农民催租一样” 这个比喻真牛!

关键是 set /p 显示时能不换行。

当然九九乘法表用 echo 也能做到(namejm 基础上改的):
  1. @echo off&setlocal enableDelayedExpansion
  2. for /l %%a in (1 1 9) do (
  3.  for /l %%b in (1 1 %%a) do (
  4.   set/a res=%%a*%%b
  5.   set "res=!res! "
  6.   set L%%a=!L%%a!  %%ax%%b=!res:~0,2!
  7.  )
  8.  echo.!L%%a!
  9. )
  10. pause>nul
复制代码

作者: p05401144    时间: 2009-1-13 15:44

“关键是 set /p 显示时能不换行”  谢谢版主大人指出
可我在运行你的程序时没有显示结果,是不是哪里出了点小问题。
作者: wxcute    时间: 2009-1-13 16:05     标题: 回复 3楼 的帖子

存为 xx.cmd 试试,我这儿可以[XP SP3]
  1. @echo off
  2. setlocal enableDelayedExpansion
  3. for /l %%a in (1 1 9) do (
  4.  for /l %%b in (1 1 %%a) do (
  5.   set/a res=%%a*%%b
  6.   set "res=!res! "
  7.   set "L%%a=!L%%a!%%bx%%a=!res:~0,2! "
  8.  )
  9.  echo.!L%%a!
  10. )
  11. pause>nul
复制代码
结果:
1x1=1  
1x2=2  2x2=4  
1x3=3  2x3=6  3x3=9  
1x4=4  2x4=8  3x4=12 4x4=16 
1x5=5  2x5=10 3x5=15 4x5=20 5x5=25 
1x6=6  2x6=12 3x6=18 4x6=24 5x6=30 6x6=36 
1x7=7  2x7=14 3x7=21 4x7=28 5x7=35 6x7=42 7x7=49 
1x8=8  2x8=16 3x8=24 4x8=32 5x8=40 6x8=48 7x8=56 8x8=64 
1x9=9  2x9=18 3x9=27 4x9=36 5x9=45 6x9=54 7x9=63 8x9=72 9x9=81


[ 本帖最后由 wxcute 于 2009-1-13 16:34 编辑 ]
作者: p05401144    时间: 2009-1-13 16:21

还是不行啊,我用的也的xp sp3(ghost安装的)
请问一下*.bat和*.cmd 有什么区别?

[ 本帖最后由 Batcher 于 2009-5-16 13:32 编辑 ]
作者: lhjoanna    时间: 2009-1-13 18:47

分析的很好,感谢你写出来大家一起分享。和你的情况差不多,我也是刚学批处理不久就碰到此题了,同样是学过C,并且自己做出来的方法就是用echo。也曾为发现set /p的妙用而欣喜。我想学习就是要有探索的精神,保持下去,假以时日,你也会成为高手的,一起努力!
     对于以上的set /p的用法,我来补充几点:
     1、set /p=...<nul并不是可以代替echo,它们的区别在于前者并不换行。
     2、set /p=...<nul表示从空设备读入值,等同于set /p var=...<nul。但要注意的是,此句并没有把值赋予var,原因我还不清楚,也没找到比较权威的解释,明白此点可以省去些无谓的代码。
     3、利用此句set /p=可以实现一些特殊的要求,比如想要只输入回车符程序才继续执行,其他输入任何字符都对程序无影响。或者在某种程度上可以代替pause>nul。
     4、利用此句set /p var=<a.txt,可以把a.txt中第一行的值赋予变量var,这种情况下可以代替for命令。
     5、set /p=...<nul可以屏蔽一些特殊的字符,如果往一个文件中写入字符串,对于echo无法实现的特殊字符,此句可以实现。
     另外set /a,set命令等还有许多性质,只要在自己实践中细心总结,会有很多收获的。加油!
作者: 随风    时间: 2009-1-13 19:21

set /p var=abcd<nul
为什么没有给var赋值,我是这样理解的
set /p var=请输入
如果在此时你输入任何内容,如 abc 再回车,那么此时 var的值就是 “abc” 而不是 “请输入abc”
同理, set /p var=abcd<nul  语句中 abcd 应该就相当于 set /p var=请输入 中的 “请输入” 而 <nul 则相当于回车。
总结就是
set /p var=abcd  此时是等待用户输入即:给var赋值,而 <nul 是代表从空设备输入也就是没有输入内容,但还是输入了,也是相当于按了回车,等同 set /p var=abcd<a.txt (注:a.txt文件内容为空)
如下代码同样输出不换行
  1. @echo off
  2. cd.>c.txt
  3. set /p var=1234<nul
  4. set /p var=abcd<c.txt
  5. echo 5678
  6. pause
复制代码

[ 本帖最后由 随风 于 2009-1-13 19:31 编辑 ]
作者: p05401144    时间: 2009-1-13 19:29

谢谢你们的教导,宛如提醐灌顶。
我一定好好学习批处理,希望有朝一日能成为像你们这样的高手
作者: wxcute    时间: 2009-1-13 19:33

set /p 参数用法:
set /p <变量名>="提示信息"
其中变量名可省略,提示信息不会赋值给变量,赋给变量的值是你输入的值。

特殊:
  一、set 与参数 /p 之间的空格可省略;
  二、变量名可省略,用来专门输出提示信息;
  三、可指定从 nul 设备中输入,与第二点结合相当于不换行的 echo (当然这时不省略变量名也可);
  四、指定从文件中输入,相当于将文件的第一个非空行内容赋值给变量。

<nul,涉及到重定向
用法
作用 或 效果相当于
set /p ala=输入字母:set /p ala=输入字母:<con
二者略有区别,不必深究。详细参考搜索重定向。
set/p num=提示<num.txt将 num.txt 的第一个非空行内容赋值给变量 num;但 “提示” 这两个字不会赋给它。
与 set/p num=<num.txt 唯一不同之处是前者会输出 “提示” 这两个字。
set/p=输出内容<nulset /p var=输出内容<nul
空设备是没有内容的,因此 “输出内容” 这四个字并不会赋值给变量 var。
但由于提示信息即 “输出内容” 是会显示的,因此相当于 [echo 输出内容] 但没有换行。


综上所述:
@echo off
echo 输入选择:
set /p var=
pause
@echo off
set /p var=输入选择:
pause
前者有换行
set /p str=信息<nul
set/p=信息<nul
echo+|set/p=信息
echo 信息
后者有换行


[ 本帖最后由 wxcute 于 2009-1-13 19:35 编辑 ]
作者: p05401144    时间: 2009-1-13 20:22     标题: 回复 4楼 的帖子

成功了,刚才好像是我的记事本出了问题,无论写什么程序都出错
再次谢谢了
作者: Batcher    时间: 2009-1-13 21:02     标题: 回复 10楼 的帖子

注意记事本的编码格式,一定要是ANSI编码,如果是UNICODE编码会出错。
作者: coolhui    时间: 2009-1-14 00:54

很精彩的讨论啊,学习了~~~
作者: xunaco    时间: 2009-1-14 09:12

2楼的高手
echo.!L%%a!
是什么意思?能指点一下吗?
作者: leikaihua    时间: 2009-1-17 19:39

@echo off
echo 1x1=1  
echo 2x1=2   2x2=4   
echo 3x1=3   3x2=6   3x3=9   
echo 4x1=4   4x2=8   4x3=12  4x4=16  
echo 5x1=5   5x2=10  5x3=15  5x4=20  5x5=25  
echo 6x1=6   6x2=12  6x3=18  6x4=24  6x5=30  6x6=36  
echo 7x1=7   7x2=14  7x3=21  7x4=28  7x5=35  7x6=42  7x7=49  
echo 8x1=8   8x2=16  8x3=24  8x4=32  8x5=40  8x6=48  8x7=56  8x8=64  
echo 9x1=9   9x2=18  9x3=27  9x4=36  9x5=45  9x6=54  9x7=63  9x8=72  9x9=81
pause  


我实在看不懂 什么是延迟变量  谁能用超通俗的语言讲一下么,
set "res=!res! "
  set "L%%a=!L%%a!%%bx%%a=!res:~0,2! "
这两句什么意思啊  
本人头脑愚钝,希望各位老师讲一下么
作者: Batcher    时间: 2009-1-17 20:06     标题: 回复 14楼 的帖子

多看教程

什么是延迟环境变量扩展?
http://bbs.bathome.net/thread-3083-1-1.html

变量延迟详解
http://bbs.bathome.net/thread-2898-1-1.html

什么情况下该使用变量延迟
http://bbs.bathome.net/thread-2899-1-1.html

一个变量嵌套变量的问题
http://bbs.bathome.net/thread-2900-1-1.html

什么时候使用延迟变量?为什么要使用?
http://bbs.bathome.net/viewthread.php?tid=112

延迟变量通俗解释
http://bbs.bathome.net/viewthread.php?tid=354
作者: taojunyi    时间: 2009-1-21 12:24     标题: 我的理解

set /p =aaa<nul
我的理解是:
1、从空设备读入空内容给空变量,即然是空内容,所以不换行。不能把<nul理解为回车,回车换行,而<nul是不换行的
2、=后面的是提示文字,是用来和用户进行交流的,只显示不赋值。
作者: 5810239q    时间: 2009-3-25 16:52

批处理真是难学呀!幸好有这么好的教程
作者: sjzong    时间: 2009-4-11 17:30

看来要认真点才可以的!
作者: syqtkj    时间: 2009-12-3 15:50     标题: 关于批量修改文件名

列如:我想把某目录下的一个文件夹下所有文件夹里的文件,只要文件名字中带有"大家好"字样的文件全部替换成"你们好"
请问大家该如何写批命令,万分感谢!
作者: caimingbing    时间: 2010-1-10 10:42

俺都看不懂的,努力学习中
作者: baixfps    时间: 2010-1-19 00:55

现在基本上,,我一点都不懂。。以后努努学习。只知道回贴就OK了!
作者: summerflower    时间: 2010-1-22 11:24

namejm的代码确实很完美,我就没有想到要对齐的问题
作者: ewxf    时间: 2010-1-27 00:49     标题: 讨论很精彩

真的让我弄懂很多东西,谢谢!
作者: wc726842270    时间: 2010-9-15 09:27

讨论的十分精采。把我多日对SET /P的不理解彻底澄清了
作者: dl206699    时间: 2010-9-20 13:30

set "res=!res!  " %======此处用来对齐=========%
                set/p=%%ax%%b=!res:~0,2!  <nul
第一句对齐具体是怎么实现的啊?第二局的!res:~0,2!,这部分的命令语法是什么。谢谢大家
作者: dl206699    时间: 2010-9-20 13:42

随风老大,现身吧,看了你好多帖子,写的很好很通俗易懂啊,期待在你的指导下我也成为一个批处理高手
作者: lvsehuaxue    时间: 2010-9-20 17:52     标题: 又进了一小步

感谢各位的高见,是我等菜鸟获益匪浅!




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2