如何在批处理脚本中搜索用户给定的数组中的特定值

问题描述:

我正在制作一个批处理脚本,其中我需要向用户请求输入。从用户获得输入后,它现在将获取该值并在数组内搜索它。如果它在里面,它将继续到goto。如果失败,则转到另一个goto如何在批处理脚本中搜索用户给定的数组中的特定值

下面是我的代码

@echo off 
set "Array[0]=830486600" 
set "Array[1]=832180943" 
set "Array[2]=867672488" 
set "Array[3]=851091583" 
set "Array[4]=105670350" 
set "Array[5]=871749063" 
set "Array[6]=831425861" 
set "Array[7]=833386470" 
set "Array[8]=845221250" 
set "Array[9]=839863683" 
set "Array[10]=837778733" 
set "Array[11]=866184944" 
set "Array[12]=863514631" 
set "Array[13]=868073035" 
set "Array[14]=841618088" 
set /p code=Enter code: 

for /F "tokens=2 delims==" %%s in ('set Array[') do (
    if "%code%" == "%%s"(
     goto breakit 
    )else (
     goto breakit2 
    ) 
) 
pause 


:breakit 
echo inside! 
pause 
goto eof 


:breakit2 
echo not inside 
pause 
goto eof 

上面的例子只是一个样本,但我一直面临的一个问题是,当其输入的用户类型的空格,则退出程序,它不读取有效的输入,即使它是数组内的确切值,它仍然不会读取它。

问题的直接原因是批次在布局时非常敏感。

if "%code%" == "%%s"(

相当字面上理解为“如果"%code%" == "%%s"(” - 第二个字符串被解释为(和批次认为没有“好了,我该怎么办,如果字符串匹配吗?”。

对此的解决方案是增加隔板像空间

if "%code%" == "%%s" (

(类似地,尽管)else作品,else(不那么) else (通常为所使用的格式)

下一页问题:goto将执行转移到目标标签。它不提供退货,因此在第一次比较后,执行转移:breakit[2],然后将从那里继续。结果可能是breakit然后继续breakit2

它不是为goto eof。您的代码中没有标签:eof(并且也不应该存在) - 特定的语法goto :eof(带冒号)表示go to end-of-physical-file,它终止该例程。

因此,您需要执行子程序breakit[2]call :breakit[2]。冒号指定该子程序是内部的(在这批批次中)标签:breakit[2](并且期望它将以goto :eofexit[/b]终止)。如果冒号缺失,即使标签:breakit[2]存在于当前代码中,也会尝试运行可执行文件breakit[2]

的最后一个问题是,如果code包含空间==将尝试匹配code contents针对每个加载到阵列的串。由于没有数组中的字符串包含空格,因此无匹配。

如果意图是如果的(空格,逗号,分号)的任何code分隔的字符串匹配中找到的字符串在array然后各个串必须匹配相匹配;因此请使用for迭代code中的字符串。

现在,这意味着是的,你会发现一个匹配 - 毫无疑问,报告匹配哪个子字符串是比较有用的,而不是仅仅报告找到匹配。为此,您需要将发现匹配的字符串传递给:breakit并累积找到的字符串。

@ECHO OFF 
SETLOCAL 
set "Array[0]=830486600" 
set "Array[1]=832180943" 
set "Array[2]=867672488" 
set "Array[3]=851091583" 
set "Array[4]=105670350" 
set "Array[5]=871749063" 
set "Array[6]=831425861" 
set "Array[7]=833386470" 
set "Array[8]=845221250" 
set "Array[9]=839863683" 
set "Array[10]=837778733" 
set "Array[11]=866184944" 
set "Array[12]=863514631" 
set "Array[13]=868073035" 
set "Array[14]=841618088" 
set /p code=Enter code: 

SET "found=" 

for /F "tokens=2 delims==" %%s in ('set Array[') do (
FOR %%c IN (%code%) DO (
    if "%%c" == "%%s" (
     call :breakit "%%s" 
    ) else (
     call :breakit2 
    ) 
) 
) 

IF DEFINED found ECHO strings found : %found% 

goto :eof 


:breakit 
echo inside! (%1) 
SET "found=%found% %1" 
goto :eof 


:breakit2 
echo not inside 
goto :eof 

注:一个metavariable(在for或参数编号%0环路控制变量..%9中的例程),包括直接~前的变量名(%%~s%~1)时检索它的价值将删除"任何封闭双引号"

+0

我可以将breakit和breakit2中的回显部分更改为更深刻的代码吗?因为如果在数组中找到用户的输入,我真的打算在breakit中创建一个文件夹。更多,否则就像这样:':firstCreateFolder md%firstFolder% goto firstFileList' then then it does it goes to another'goto' where where in request at a option。我不应该改变循环中的'call'部分或者':breakit'本身 –

+0

不管你喜欢什么。问题简单的是,如果你转到了alabel,那么执行被转移,而'call'将返回位置('call'后面的命令)保存到堆栈。达到物理结束文件返回执行并删除堆栈中的最后一个位置('exit'的确如此)。如果没有更多堆栈条目,则批处理结束。如果你愿意的话,你可以永远的意大利式代码,就像汇编程序一样。 – Magoo

,如果您将需要的值,下标您可能会简化代码很多,那就是:

@echo off 
setlocal 

set "Array[830486600]=1" 
set "Array[832180943]=1" 
set "Array[867672488]=1" 
set "Array[851091583]=1" 
set "Array[105670350]=1" 
set "Array[871749063]=1" 
set "Array[831425861]=1" 
set "Array[833386470]=1" 
set "Array[845221250]=1" 
set "Array[839863683]=1" 
set "Array[837778733]=1" 
set "Array[866184944]=1" 
set "Array[863514631]=1" 
set "Array[868073035]=1" 
set "Array[841618088]=1" 
set /p code=Enter code: 

if defined Array[%code%] (
    echo inside 
) else (
    echo not inside 
)