Board logo

标题: 请大家指点一下,这个批处理那里错了 [打印本页]

作者: fan927     时间: 2006-5-29 02:25    标题: 请大家指点一下,这个批处理那里错了

我希望输入相应的名字,出现相应的结果,可是这个批处理是错的,应该怎么写,多谢了.

@echo off
set /p a=请输入你的名字:
if "%a%"=="dog" goto dog
:dog
echo 这是一只狗
goto end

if "%a%"=="pig" goto pig
:pig
echo 这是一只猪
goto end

if "%a%"=="" goto kong
:kong
echo 您没有输入名字,请重新输入
goto end

:end
pause
作者: Wengier     时间: 2006-5-29 02:53
上面的标号使用方法不对。试试下面这个吧:

@echo off
set /p a=请输入你的名字:
if "%a%"=="dog" (echo 这是一只狗) else if "%a%"=="pig" (echo 这是一只猪) else echo 您没有输入名字,请重新输入
作者: 不得不爱     时间: 2006-5-29 09:22
可以这样改!
@echo off
set /p a=请输入你的名字:
if "%a%"=="dog" goto dog
if "%a%"=="pig" goto pig
if "%a%"=="" goto kong
:dog
echo 这是一只狗
goto end

:pig
echo 这是一只猪
goto end

:kong
echo 您没有输入名字,请重新输入
goto end

:end
pause
作者: Wengier     时间: 2006-5-29 09:36


  Quote:
Originally posted by qwe1234567 at 2006-5-29 09:22 AM:
可以这样改!
@echo off
set /p a=请输入你的名字:
if "%a%"=="dog" goto dog
if "%a%"=="pig" goto pig
if "%a%"=="" goto kon ...

这个太长了吧,上面(2楼)只需三行就完成了,而且效果跟这完全相同。
作者: arding     时间: 2006-5-29 10:22
注意!这部分不对:

  Quote:
if "%a%"=="dog" goto dog
:dog
echo 这是一只狗
goto end

if "%a%"=="dog" goto dog,
如果输入是dog当然进入下一句:dog,但是如果输入不是dog,仍然会继续到 if 语句的下一句。所以会错了。
像二楼那样,与 if 在一行,而且加上 ( ) 就如你所愿了。
作者: 3742668     时间: 2006-5-29 12:49
两个逻辑错误:
    1.3个if语句应该放在一起,而且在if语句后面应该有跳转语句避免执行下面的dog,pig以及kong标号段,楼上几位的方法可以参考。
    2.kong标号结束部分跳转不正确。

  Quote:
if "%a%"=="" goto kong
:kong
echo 您没有输入名字,请重新输入
goto end

不应该是goto end,那样的话就不会是重新输入而应该是直接退出了。正确的做法应该是在set /p前面再加上一个标号,此处跳转到set /p前面。当然,某些部分也要做相映的修改。
作者: fan927     时间: 2006-5-29 13:12
非常感谢回复小弟的大侠们,问题已经解决,主要是else的应用,我现在修改了一下,代码如下:
@echo off
:set
set /p a=请输入你的名字:
if "%a%"=="dog" goto dog else goto pig
if "%a%"=="pig" goto pig else goto kong
if "%a%"=="" goto kong
:dog
echo 这是一只狗
goto end

:pig
echo 这是一只猪
goto end

:kong
echo 您没有输入名字,请重新输入
goto set

:end
pause

可以正常完成我的要求.再次感谢!
作者: 3742668     时间: 2006-5-29 13:44
Well,问题似乎没有你想象的那么简单,问题的根本并不在于else语句,运行你的脚本,随便输入一个字符(即不在判断内的字符,例如c)就可以看出问题来了。另外你的结构似乎也有点小问题,判断是否为空的模块似乎可以取消,改为第三个if语句直接跳转应该更好。在你的代码上简单做做修改:
@echo off
:set
set /p a=请输入你的名字:
if "%a%" == "" echo 您没有输入名字,请重新输入 && goto set
call :%a% 2>nul
goto error
goto end

:dog
echo 这是一只狗
goto end

:pig
echo 这是一只猪
goto end

:error
echo 输入错误,按任意键退出...
pause>nul
exit

:end
按任意键退出...
pause>nul
exit
期待你能把它完善精简一下。
作者: 不得不爱     时间: 2006-5-29 13:47
下面的比较短!
@echo off
set a=
:a
set /p a=请输入你的名字:
if %a%#==dog# (echo 这是一只狗) else if %a%#==pig# (echo 这是一只猪 ) else if %a%#==# (echo 您没有输入名字,请重新输入 & goto a) else (echo 输入错误,按任意键退出...)
pause

[ Last edited by qwe1234567 on 2006-5-29 at 14:16 ]
作者: fan927     时间: 2006-5-29 13:52
是啊,我也发现输入错误字符这个问题了,多谢!
另外请问,我如果%a%="dog" or "gou" or "狗"应该怎么表示?是不是要 if 3次?
if "%a%"=="dog" goto dog else goto pig
if "%a%"=="gou" goto dog else goto pig
if "%a%"=="狗" goto dog else goto pig
3742668 版主
劳您费神了!
作者: fan927     时间: 2006-5-29 13:54
多谢qwe1234567版主 ,不过用我的复杂一点的格式我觉得比较习惯.呵呵可能我是菜鸟的关系吧.
作者: 3742668     时间: 2006-5-29 14:26


  Quote:
Originally posted by fan927 at 2006-5-29 13:52:
是啊,我也发现输入错误字符这个问题了,多谢!
另外请问,我如果%a%="dog" or "gou" or "狗"应该怎么表示?是不是要 if 3次?
if "%a%&q ...


@echo off
set /p a=输入:
goto %a%

:dog
:狗
echo 狗
pause
使用多个标号可以达到意想不到的效果。至于标号格式与else格式,可以酌情考虑使用,各有各的好。
作者: 不得不爱     时间: 2006-5-29 14:37
7楼的有问题!如果输入的是dog pig 也外的它也要跳到pig行!
作者: 不得不爱     时间: 2006-5-29 14:42
如果是12楼的话,输入的字符没有对应的行号会出错的!
作者: 不得不爱     时间: 2006-5-29 14:53
另外如果%a%="dog" or "gou" or "狗"都要跳到dog的话可以用下面的;
for %%1 in (dog gou 狗) do if %a%#==%%1 goto dog
作者: willsort     时间: 2006-5-29 19:58
Re fan927:

      楼主在7楼10楼的else用法实际上是错误的。在cmd中else子句必须位于if子句的尾部之后,而尾部的标志是右圆括弧 ")",具体参见[1]。所以,楼主的else因为直接跟随在goto label之后而被忽略,所以是无效的。

      如果使用 f "%a%"=="dog" (goto dog) else goto pig 使else子句有效,则程序的流程分支将会不符合预期,即%a%不为dog即去goto pig,以后的if语句将均被忽略。

Re Wengier:

      if/goto样式和if/else样式的选择,实际上主要取决于个人的编写风格,比如从DOS Batch中成长的我,便喜欢使用goto样式的分支跳转,因为它具有更强的兼容性,而且这样的样式可以使我快速浏览代码中基本的分支流程,而不需要滚动和翻页。

      其它的选择理由还有一些,比如我不太喜欢每行语句的长度超过80个字符,这不仅仅是DOS下文本编辑器所带来的遗留习惯,主要是它可以增加阅读代码时的休息停顿频率,以提高代码的可阅读性。毕竟在大多数情况下,几个短句总是比一个等价的长句更易于理解。当然,if/else样式也可以改成短句型式,但是这样它就不再简洁了。

[1]引自cmd@WinXP的set命令行帮助信息

  Quote:
ELSE 子句必须在 IF 之后出现在同一行上。例如:

    IF EXIST filename. (
        del filename.
    ) ELSE (
        echo filename. missing.
    )

因为 del 命令需要用一个新行终止,以下子句不会有效:

IF EXIST filename. del filename. ELSE echo filename. missing

由于 ELSE 命令必须与 IF 命令的尾端在同一行上,以下子句也
不会有效:

    IF EXIST filename. del filename.
    ELSE echo filename. missing

如果都放在同一行上,以下子句有效:

    IF EXIST filename. (del filename.) ELSE echo filename. missing


作者: Wengier     时间: 2006-5-29 23:22
Willsort:

其它理由我同意,不过如说到兼容性,那也是没有办法的。如果楼主是在编写DOS批处理文件的话,那自然要用DOS的语法,而且这也是我最常用到的。但是,楼主在一开头就用到了“SET /P”这种用法,显然这是不能在DOS下运行的,因此我当时就判定他是在编写NT脚本。因此,这也就无法再顾及对DOS下的兼容性了。而对于NT脚本来说,当然最好使用NT脚本中比较简洁的方法,而且if/else与goto相比似乎不是那么容易出错(如1楼中的错误)。
作者: fan927     时间: 2006-5-30 02:05
多谢大家热情回复,这次应该是彻底搞定了


@echo off

:set
set /p a=请输入你的名字:
if "%a%"=="dog" (goto dog) else if "%a%"=="pig" (goto pig) else if "%a%"=="" (goto set) else goto err

:dog
echo 这是一只狗!
goto end

:pig
echo 这是一只猪!
goto end

:err
echo 输入错误!!
goto end

:end
set a=
goto set
pause>nul
作者: 3742668     时间: 2006-5-30 12:29
彻底搞定了?Really?恐怕言之过早了吧。
    不必说最后的end部分无法退出,最后一句pause.nul百无一用;也不必说三个标号段+if/else的结构是取二者之短,导致代码冗余度增加,可扩展性降低;单是出错处理,光靠一句else goto err是远远不够的。在set /p语句运行时,可以尝试输入以下各种字符:
    1.一个引号       "
    2.引号+双等号  "=="?"
   事实说明:革命尚未成功,同志仍需努力。期待你能综合前几楼之长,把这个脚本真正地搞定。
作者: fan927     时间: 2006-5-30 15:09
多谢3742668版主,这样我认为可以了吧,我接触批处理也就半个月左右,您的指点我还一时理解不了,以后还请多多指教!

@echo off
:set
set a=
set /p a=请输入你的名字(可选dog,pig or end):
if "%a%"=="dog" (
goto dog
) else if "%a%"=="pig" (
goto pig
) else if "%a%"=="" (
goto set
) else if "%a%"=="end" (
goto end
) else goto err

:dog
echo 这是一只狗!
goto set

:pig
echo 这是一只猪!
goto set

:err
echo 输入错误!!
goto set

:end
pause