2017-10-18 2 views
0

Je crée un script batch dans lequel je dois demander une entrée à l'utilisateur. Après avoir reçu l'entrée de l'utilisateur, il va maintenant obtenir la valeur et la rechercher dans le tableau. S'il est à l'intérieur, il passera à goto. Si elle échoue, à un autre goto.Comment rechercher une valeur spécifique donnée par l'utilisateur dans un tableau en script batch

Ci-dessous est échantillon de mon code

@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 

Au-dessus est juste un échantillon, mais les problèmes que j'ai été confronté est que, lorsque les types d'utilisateur dans ses entrées avec des espaces, il quitte le programme, il ne pas lire les entrées valides même si c'est la valeur exacte dans le tableau, il ne le lit toujours pas.

Répondre

1

La cause directe de votre problème est que le lot est très sensible à la mise en page.

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

est littéralement considéré comme « si "%code%" == "%%s"( » - la deuxième chaîne est interprété comme contenant le ( et le lot ne voit pas « bien, que dois-je faire si les chaînes correspondent? ».

La solution est d'ajouter un séparateur comme un espace

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

(De même, alors que )else œuvres, else( ne le fait pas ) else ( est généralement le format utilisé)

problème suivant : goto transfère l'exécution à l'étiquette de destination. Il ne fournit pas de retour, donc après la première comparaison, l'exécution est transférée à :breakit[2] et procédera ensuite à partir de là. La conséquence peut être que breakit va alors procéder à breakit2.

Ou s'il n'y avait pas le goto eof. Il n'y a pas d'étiquette :eof dans votre code (et il ne devrait pas y avoir) - la spécifique syntaxe goto :eof (avec les deux points) signifie go to end-of-physical-file qui termine la routine.

Vous avez donc besoin de call :breakit[2] qui exécute un sous-programme breakit[2]. Le deux-points spécifie que le sous-programme est interne (dans ce lot) à l'étiquette :breakit[2] (et l'attente est qu'il se terminera par goto :eof ou exit[/b]). Si les deux-points sont manquants, une tentative sera faite pour exécuter le exécutablebreakit[2], même si l'étiquette :breakit[2] existe dans le code actuel.

Le dernier problème est que si code contient un espace alors le == tentera de faire correspondre code contents contre chacune des chaînes chargées dans le tableau. Aucune ne correspond car aucune des chaînes du tableau ne contient d'espaces.

S'il est prévu qu'un match se trouve si une du (espace, virgule, point-virgule) séparées des chaînes en code correspond à une chaîne en array alors doit correspondre les chaînes individuelles; par conséquent, utilisez un for pour itérer les chaînes dans code. Maintenant, cela signifie que oui, vous trouvez une correspondance - sans doute, il serait utile de signaler quelle sous-chaîne (s) correspondait plutôt que de rapporter simplement qu'une correspondance a été trouvée. Pour ce faire, vous devez passer la chaîne pour laquelle une correspondance a été trouvée à :breakit et accumuler la ou les chaînes trouvées.

@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 

Note: pour une metavariable (la variable de contrôle de boucle dans un for ou le numéro de paramètre% 0 ..% 9 dans un sous-programme), y compris ~ directement avant le nom de la variable (%%~s ou %~1) lorsque récupérer sa valeur enlèvera " des guillemets doubles enserrant "

+0

Puis-je changer la partie d'écho dans breakit et breakit2 en un code beaucoup plus profond? parce que ce que j'ai vraiment l'intention de faire dans breakit est de créer un dossier si trouve l'entrée de l'utilisateur dans le tableau. plus ou moins comme ceci, ': firstCreateFolder md% firstFolder% goto firstFileList' alors s'il ne le fait pas il va à un autre' goto' où il demande une option. Je ne fais pas si je devrais changer la partie 'call' dans la boucle ou le': breakit' lui-même –

+0

Tout ce que vous aimez. Le problème est simplement que si vous 'goto alabel', alors l'exécution est transférée, alors que' call' enregistre l'emplacement de retour (la commande qui suit 'call') dans une pile. Atteindre une fin de fichier physique renvoie l'exécution à et supprime le dernier emplacement sur la pile ('exit' fait la même chose). S'il n'y a plus d'entrées de pile, le lot se termine. Vous pouvez toujours utiliser le code spaghetti 'goto's si vous voulez - tout comme l'assembleur. – Magoo

0

vous pouvez simplifier votre code beaucoup si vous déplacez les valeurs souhaitées dans les indices, qui est:

@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 
)