2015-11-30 190 views
0

我似乎在制作这个程序时遇到了很多麻烦。 我终于只有一个错误。这是我的代码:批处理文件“If”语句错误

:tutq 
echo What is the first letter of your name? 
echo 1(A 
echo 2(B 
echo 3(C 
echo 4(D 
echo 5(E 
echo 6(F 
echo 7(G 
echo 8(H 
echo 9(I 
echo 10(J 
echo 11(K 
echo 12(L 
echo 13(M 
echo 14(N 
echo 15(O 
echo 16(P 
echo 17(Q 
echo 18(R 
echo 19(S 
echo 20(T 
echo 21(U 
echo 22(V 
echo 23(W 
echo 24(X 
echo 25(Y 
echo 26(Z 
set /p tutnum= 
If not defined !tutnum! (
cls 
goto tutq 
) 
If "!tutnum!" == "1" (
set "tutlet=A" 
goto tutp2 
) 
If "!tutnum!" == "2" (
set "tutlet=B" 
goto tutp2 
) 
If "!tutnum!" == "3" (
set "tutlet=C" 
goto tutp2 
) 
If "!tutnum!" == "4" (
set "tutlet=D" 
goto tutp2 
) 
If "!tutnum!" == "5" (
set "tutnum=E" 
goto tutp2 
) 
If "!tutnum!" == "6" (
set "tutlet=F" 
goto tutp2 
) 
If "!tutnum!" == "7" (
set "tutlet=G" 
goto tutp2 
) 
If "!tutnum!" == "8" (
set "tutlet=H" 
goto tutp2 
) 
If "!tutnum!" == "9" (
set "tutlet=I" 
goto tutp2 
) 
If "!tutnum!" == "10" (
set "tutlet=J" 
goto tutp2 
) 
If "!tutnum!" == "11" (
set "tutlet=K" 
goto tutp2 
) 
If "!tutnum!" == "12" (
set "tutlet=L" 
goto tutp2 
) 
If "!tutnum!" == "13" (
set "tutlet=M" 
goto tutp2 
) 
If "!tutnum!" == "14" (
set "tutlet=N" 
goto tutp2 
) 
If "!tutnum!" == "15" (
set "tutlet=O" 
goto tutp2 
) 
If "!tutnum!" == "16" (
set "tutlet=P" 
goto tutp2 
) 
If "!tutnum!" == "17" (
set "tutlet=Q" 
goto tutp2 
) 
If "!tutnum!" == "18" (
set "tutlet=R" 
goto tutp2 
) 
If "!tutnum!" == "19" (
set "tutlet=S" 
goto tutp2 
) 
If "!tutnum!" == "20" (
set "tutlet=T" 
goto tutp2 
) 
If "!tutnum!" == "21" (
set "tutlet=U" 
goto tutp2 
) 
If "!tutnum!" == "22"(
set "tutlet=V" 
goto tutp2 
) 
If "!tutnum!" == "23" (
set "tutlet=W" 
goto tutp2 
) 
If "!tutnum!" == "24" (
set "tutlet=X" 
goto tutp2 
) 
If "!tutnum!" == "25" (
set "tutlet=Y" 
goto tutp2 
) 
If "!tutnum!" == "26" (
set "tutlet=Z" 
goto tutp2 
) 
:tutp2 
echo Congrats! 
echo If you did the exersize correct 
echo The first letter of your name should be "!tutlet!" 
pause 

不管怎么说,如果你能向我解释什么是错的。

+1

什么错误你好吗?初看之下,我可以看到你的代码有两个可能的问题,但是因为你发布的内容并不是以'@echo off'开始的,我假设这不是整个代码。 – SomethingDark

+0

@SomethingDark完整的代码有“@回响”和“SETLOCAL enabledelayedexpansion”至于在收到错误似乎做什么都没有用什么我输入。它只是闪烁,并保持在屏幕上。 –

+0

下次请不要在别处发布您的代码并链接到它。把它放在你的问题。你可以画下来连接到它,所以编辑你的问题,现在做它可能是一个好主意。 –

回答

1

你的代码实际上是按照你所说的去做的,它的速度非常快,你无法注意到它。

当您检查是否存在变量时,请勿将其包装在%!中。 if not defined varname基本上说,“如果没有变量叫'varname',那么这样做...”;当您用%!围绕它时,可以用它的值替换该变量。如果我在提示符处输入10,代码将会显示“如果没有名为10的变量,则清除屏幕并返回tutq。”因为没有变量叫做10,所以你陷入了无限循环。

更改If not defined !tutnum! (If not defined tutnum (并且您的代码将工作。

0

您已经接受了一个很好的答案 - 请留下来。这是可能证明有用的补充信息,如果不是,那么对其他面临同样问题的人也是如此。

@ECHO OFF 
SETLOCAL ENABLEDELAYEDEXPANSION 
SET "letequ=a(1 b(2 c(3 d(4 e(5" 
:tutq 
cls 
FOR %%a IN (%letequ%) DO echo %%a 
SET "tutnum=" 
SET /p "tutnum=What is the first letter of your name? " 
IF NOT DEFINED tutnum GOTO tutq 
FOR %%a IN (%letequ%) DO (
SET letterandnumber=%%a 
SET "letter=!letterandnumber:~0,1!" 
SET "number=!letterandnumber:~2!" 
IF "!number!"=="%tutnum%" (
    ECHO The first letter of your name is "!letter!"&pause&GOTO :EOF) 
) 
GOTO tutq 

所以 - 我没有刻意去完成设定字母/数字。如何做到这一点应该是相当明显的。

请注意设置字符串值的技巧。该语法可确保分配的值中包含而不是后面的空格,这有时会导致问题。例如,

SET tutnum= 

应清除tutnum出来,这意味着只要cmd关注环境,它具有没什么价值如果有对流浪(和方便不可见的)空间行尾,它将被设置为那些空格,并且if defined tutnum将是true

SET "tutnum=" 

将清除tutnum如所期望,杂散空格或没有。

只是一个set /p之前设置的变量似乎是多余的,但如果一个set /p的反应仅仅是输入那么变量将保持不变 - 它不会自动没有价值可以假定。这种技术可以用来指定一个默认值

set "var=default" 
set /p "var=prompt-string" 

将离开default分配给var如果用户回答输入

这可以用于像

set "var=default" 
set /p "var=prompt-string [%var%]" 

显示给用户如果用户回复将使用的值输入

下一个要检查的项目是for循环。 for会受到各种暗中捣鬼的,但基本就是

for %%x in (list of items separated by spaces) do something 

其中依次列表中每个项目被分配到%%a,所以在列表leteq每个项目又被分配到%%a%%a采用值 “一(1”, “b(2” “C(3”, “d(4” 和 “e(5”,则确实东西具有该值。

在的情况下分析条目部分代码东西

SET letterandnumber=%%a 
SET "letter=!letterandnumber:~0,1!" 
SET "number=!letterandnumber:~2!" 
IF "!number!"=="%tutnum%" (
    ECHO The first letter of your name is "!letter!"&pause&GOTO :EOF) 

的这里目的是值在%%a例如: “C(3”。我们不能做%%a的直接子字符串,所以我们将%%a的值分配给letterandnumber,并将子字符串指定为

子串的语法是

%var:~m,n% 
  • 如果m> = 0,则子串的开始是var第m字符,起始于 “字符0”
  • 若m是< 0,则子串的开始是从端第m字符的var
  • 如果n> 0,则n子串的长度
  • 如果n为< 0,则子串的端部是从端的var
  • Ñ也可以省略第n字符。如果省略,子串是“从开始位置到结束”
  • %可以是!delayedexpansion模式

所以letter设置为~0,1即,用于letterandnumber 1的长度的第一个字符并且类似地number被设置为~2-直到字符串结尾的第三个字母。

由于letterandnumber设置为循环(或任何括号中的语句序列,又名“一个块”),那么它可能会显示为两个单独的值。 %letterandnumber%指代在块首次遇到和解析时的值!letterandnumber!在运行时参考值,因为它可能在块内设置。 !var!语法只有在先前执行setlocal enabledelayedexpansion命令时才有效。

原因是cmd%var%替换为当前值var,然后检查语句的有效性。 !var!不被替换,直到该块是执行

这个序列的结果是显著,如果不理解会导致一些轰轰烈烈的头划伤。

假设我们有(注意,近距离括号ASE使用,不打开)

SET "letequ=a)1 b)2 c)3" 
FOR %%a IN (%letequ%) DO echo %%a 

这将导致一个语法错误因为cmd将首先取代leteq其当时的价值和然后解析它,所以它看到

FOR %%a IN (a)1 b)2 c)3) DO echo %%a 

假定第一紧密括号结束列表并预期do但发现1因此它报告了问题。解决这个问题

的一种方式是逃逸的通过用插入符号前它误解^

SET "letequ=a^)1 b^)2 c^)3" 
FOR %%a IN (%letequ%) DO echo %%a 

cmd现在看到FOR %%a IN (a^)1 b^)2 c^)3) DO echo %%a并识别出^)指“这个括号是数据,而不是命令的一部分“它因此对语法感到满意,并继续执行代码。

另一种方式是这样的(如果delayedexpansion有效)

SET "letequ=a)1 b)2 c)3" 
FOR %%a IN (!letequ!) DO echo %%a 

cmd不能替代的值,直到命令后已通过有效性检查,因此不会引发错误。