-1

I would like to prevent user's choices except default options defined in the relevant menus.

ECHO Select a file
ECHO.
ECHO 1. Process File and commands
ECHO 2. Another File and commands
ECHO 3. Yet another file and its commands
ECHO 4. Disconnect
ECHO 5. Exit
ECHO.
set /p choice="Choose an option: "
if "%choice%"=="1" goto smenu_1 
if "%choice%"=="2" goto smenu_2
if "%choice%"=="3" goto smenu_3
if "%choice%"=="4" goto smenu_4
if "%choice%"=="5" goto End



:smenu_1
ECHO Select another option
ECHO.
ECHO 1 - This is an option
ECHO 2 - Back to Start
ECHO.
SET /P M=Choose an option:
IF %M%==1 GOTO This_Submenu_Does_Multiple_Commands
IF %M%==2 GOTO start

This is my sample code. In the main menu, if I enter "6", it automatically goes to first sub menu. I tried for many options offered here in similar questions or through the web like input validation or something similar. What I want to have user to enter one of the numbers given in the options. For instance, in main menu if "6" chosen or maybe "25", it should warn the user that a wrong option selected and give a try more. I would like to have this for all sub menus. In addition, yet another question arises at this point: Menu options may be more than 30 options meaning that may not be only single digits. Could you show me how to limit user input as many as menu options (including submenu options may vary to the number of their own options). Thanks in advance.

Murray
  • 57
  • 7
  • 1
    Use choice, not set /p, which allows users to corrupt your code via command injection. `For /f "Delims=" %%G in ('Choice /n /c:12345')Do If not %%G equ 5 (goto:smenu_%%G)Else Goto:Eof` – T3RR0R Sep 13 '21 at 08:29
  • @T3RR0R what if the number of options are more than 9? How can I overcome it when it comes to double digits? As far as I remember tha choice command only accepts 0123456789. – Murray Sep 13 '21 at 08:48
  • 1
    [It accepts much more than 0-9.](https://stackoverflow.com/a/41456737/12343998) – T3RR0R Sep 13 '21 at 09:07
  • @T3RR0R Okay. Thank you. I didn't know. I will check it out. – Murray Sep 13 '21 at 10:48
  • 1
    You cannot control which key(s) the user decides to press/enter, you can only control what happens as a result of that input. Please do not fall into the trap of expecting the inputter not to mis-type, or to abide by a typed instruction, you're programming a series of commands based upon responses, you are not controlling the inputter's response. – Compo Sep 13 '21 at 11:46
  • @Compo clearly understood my mistake regarding my start point. Thank you very much. – Murray Sep 13 '21 at 12:05

2 Answers2

2

If you still want to use consecutive numbers, and wish for the possibility of having more than nine possible entries you can do it using exactly the same method, as I used in my answer to your previous question. It still uses Set /P, but uses the Set command with FindStr to perform the input validation.

Example:

@Echo Off
SetLocal EnableExtensions

:Menu
ClS
Echo Menu of options
Echo(
Echo  1. Process file and commands
Echo  2. Another file and commands
Echo  3. Yet another file and commands
Echo  4. And another file and commands
Echo  5. A different file and commands
Echo  6. Some other file and commands
Echo  7. Alternative file and commands
Echo  8. Perhaps this file and commands
Echo  9. Or even this file and its commands
Echo 10. Disconnect
Echo 11. Exit
Echo(

For /F "Delims==" %%G In ('"(Set option) 2>NUL"') Do Set "%%G="
Set /P option="Please type your chosen option number, and press ENTER>"
Set option | %SystemRoot%\System32\findstr.exe /R "^option=[123456789]$ ^option=1[01]$" 1>NUL || GoTo Menu

:Validated
ClS
Echo(
Echo Your chosen option was %option%
%SystemRoot%\System32\timeout.exe /T 5

You would simply change the match strings for findstr.exe as needed when your number of options change. For example for twenty seven options (1..27), "^option=[123456789]$ ^option=1[0123456789]$ ^option=2[01234567]$". To learn how to use FindStr, please open a Command Prompt window, type findstr /? and press the ENTER key.

Compo
  • 34,184
  • 4
  • 22
  • 36
  • 1
    Based upon those examples in your comment above @Murray, have you tried `GoTo submenu%option%`? Or using the examples in your question code submission, `GoTo smenu_%option%`! – Compo Sep 13 '21 at 14:26
  • 1
    And just to clarify, you can essentially replace the entire `:Validated` label and code within it, with that command. _Although for extra safety, just in case you neglect to have a labelled section for every option, (accidentally), use `GoTo smenu_%option% 2>NUL || GoTo Menu` which would at least take the end user back to the option selection, should such a scenario have occurred_. – Compo Sep 13 '21 at 14:39
  • Thank you very much for your effort. I applied the given code as here: `Set option | %SystemRoot%\System32\findstr.exe /R "^option=[123456789]$ ^option=1[01]$" 1>NUL || GoTo submenu_%option% 2>NUL || GoTo Menu` When I click 2, it goes to option 1 (same happens even option 3 was selected). If I select option 6 that does not in the Menu to try, CMD windows closes itself. Where am I wrong? – Murray Sep 13 '21 at 14:54
  • 1
    Perhaps this would make more sense: `Set option | %SystemRoot%\System32\findstr.exe /R "^option=[123456789]$ ^option=1[01]$" 1>NUL && (GoTo submenu_%option% 2>NUL || GoTo Menu) || GoTo Menu`. Although had you read the usage information I advised, you could also try to implement a better method using the `/V` option of `FindStr`. – Compo Sep 13 '21 at 15:11
  • It works like a charm. Thank you very much for your restless effort. Solved completely. – Murray Sep 13 '21 at 15:15
0

Add :menu as very first line of your batch, and add cls & goto menu just under the if "%choice%"=="5" goto End line.

user2956477
  • 1,114
  • 8
  • 15