2017-10-18 29 views
0

我正在製作一個批處理腳本,其中我需要向用戶請求輸入。從用戶獲得輸入後,它現在將獲取該值並在數組內搜索它。如果它在裏面,它將繼續到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 

上面的例子只是一個樣本,但我一直面臨的一個問題是,當其輸入的用戶類型的空格,則退出程序,它不讀取有效的輸入,即使它是數組內的確切值,它仍然不會讀取它。

回答

1

問題的直接原因是批次在佈局時非常敏感。

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

0

,如果您將需要的值,下標您可能會簡化代碼很多,那就是:

@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 
) 
相關問題