Calling variables do not work, what to do? - variables

Hey StackOverflow Community,
I am currently programming my own life simulator called "XinsLife". Currently I want to call a variable that I set before. But it just doesn't work. I tried everything on YouTube and SS64 and could not find what the error was. So I thought I'd ask on StackOverflow. I know this problem is basic and probably everyone can do this, but I am very new to Batch.
Any help would be appreciated.
I am currently at country choosing, so when I choose a country it has to do a variable of what I chose, then goto :savesettings, and display the country that I chose. But it does not work.
C o d e :
:countrychoosing
cls
title New Life -- Country choosing
echo.
echo Choose your country:
call :echo-align center "United States"
call :echo-align center "United Kingdom"
call :echo-align center "China"
call :echo-align center "India"
call :echo-align center "More countries to come soon!"
set /p choosecountry=
if "%choosecountry%" equ 1 (
set chosecountry = United States
goto savesettings
)
if "%choosecountry%" equ 2 (
set chosecountry = United Kingdom
goto savesettings
)
if "%choosecountry%" equ 3 (
set chosecountry = China
goto savesettings
)
if "%choosecountry%" equ 4 (
set chosecountry = India
goto savesettings
)
:savesettings
call %chosecountry%
echo You chose the country "%chosecountry%". Do you want to create a save file?
choice /C:YN
if "%errorlevel%" equ 255 goto savesettings
if "%errorlevel%" equ N goto continuetest
if "%errorlevel%" equ Y goto createsavefiletest
if "%errorlevel%" equ 0 goto savesettings

Why you should use "choice", not "set /p" to accept user-input.
When you use set /p "var=Some user prompt" then var is set to the string entered from the keyboard.
But note that if the user's response is simply Enter then var will remain unchanged
All fine in theory, if you can be certain that your users will never enter an unexpected string.
Suppose the user enters 2 to your first prompt
The if statement would be interpreted as if "2" equ 2 (
Since "2" and 2 are different, the if statement will be evaluated as false. You need if "%choosecountry%" equ "2" (
So the code now becomes if "%choosecountry%" equ "2" (
Suppose the user enters United Kingdom to your first prompt, instead of the expected 2.
The if statement would be interpreted as if "United Kingdom" equ "2" ( - well, that could be fixed with some more code.
But suppose the user enters UK -yes. More code...
Suppose the entry was x"y. This would lead to a syntax error - and there are oodles of other examples like %hello which the user could enter but batch would object to.
Well - most, but probably not all of these unexpected input strings could probably be massaged to allow the cmd processor to handle them smoothly, but that's a lot of unnecessary work and code.
The better solution is to use choice which you use (but incorrectly, sorry) later in your code.
If you enter choice /? from the prompt, you get a full description of choice. In summary, you can use the command choice /C:YN where YN can be any string of unique alphamerics - a to z or a digit.
choice waits for a single character and will beep if one of the choices set by the /c: is not used.
If one of the allowed options is used, then it sets the magic variable errorlevel to a value that depends on the position of the character within the allowed string, so pressing N in response to choice /C:YN would set errorlevel to 2; for choice /C:NY to 1; for choice /C:ORANGES to 4.
magic variables are those that are set automatically like DATE, TIME, RANDOM and others. These variables should not be set as part of a program as the value set into the variable then overrides the value that the system sets.
magic variables otherwise work identically to normal user-variables, and ALL VARIABLES are strings. If the string is purely numeric then the set /a command can be used to perform some mathematical operations. (there are some esoteric exceptions to the pure-numeric string requirement - see set /? from the prompt for details)
So, to structure a choice for use from a menu, you might have
choice /C:YN
if "%errorlevel%" equ "255" goto savesettings
if "%errorlevel%" equ "2" goto continuetest
if "%errorlevel%" equ "1" goto createsavefiletest
Note that each side of the if operator ("equ") must be quoted.
OR - you may have
choice /C:YN
if errorlevel 255 goto savesettings
if errorlevel 2 goto continuetest
if errorlevel 1 goto createsavefiletest
Note that these tests must be performed in reverse-numerical order as the meaning of if errorlevel n is "if errorlevel is n or greater than n"
You could even use
choice /C:YN
goto point%errorlevel%
where :point1 is located at :createsavefiletest, :point2 at :continuetest and :point255 at :savesettings.
Note that a label is simply a location in a file, so
some code...
:xyz
:abc
:hyg
some more code...
would mean that goto xyz,goto abc andgoto hyg all do exectly the same thing.
This should enable you to solve your problem.
Batch is sensitive to spaces in an ordinary string SET statement. SET FLAG = N sets a variable named "FLAGSpace" to a value of "SpaceN". Remove Space from both sides of the =.
Use set "var=value" for setting string values - this avoids problems caused by trailing spaces. Don't assign " or a terminal backslash or Space. Build pathnames from the elements - counterintuitively, it is likely to make the process easier. If the syntax set var="value" is used, then the quotes become part of the value assigned.

Related

Batch File Randomising from 0 to Variable

For a long time I have wanted to program a game and I always thought it would be too difficult, so I started programming in the popular site Scratch (https://www.scratch.mit.edu) and doing websites with html and css.
I started to want to actually make a game with code so I am learning batch files. Unfortunately I only just started and am confused with a section on the game. I am making a game to try and recreate the game Swords and Sandals 2 to improve my knowledge of batch files. The important part of the game is the damage you deal to your opposition. Obviously you need a percentage chance for your attack to work to input luck into the game. I could easily do that but I want it so that if you have a higher level variable you will have a higher percentage chance, but if your opponent has some defence it will reduce the chance.
I did some basic maths to come up with some equations I was happy with, so here is the section of code :
if %move% equ 2 set /a tauntchance=%RANDOM%*(100+(%oppdefence%*5))/32768+1
if %move% equ 2 set /a tauntchance1=(7+(%charisma%*3))
if %move% equ 2 if tauntchance leq %tauntchance1% set /a damage= ((%charisma%*2)-%RANDOM%*1/32768+1)
if %move% equ 2 set /a energy=%energy%-%charisma%
move=The chosen option
tauntchance=A random number from 0-(100+(The opponents defence*5))
tauntchance1=(7+(Your charisma level*3))
3rd Line= If tauntchance is less than or equal to tauntchance1 then set your damage to Your Charisma Level*2 with a 50% chance to remove 1 or 0, which just stays the same.
4th Line= External variables including your energy amount.
When I run this code the window crashes. If you know if this is possible please let me know!
I have done lots of previous research without any results on this specific topic.
EDIT
With your answers it still just closes the window so I thought I would update the code from the problem onwards.
if %move% equ 2 set /a tauntchance=%RANDOM%*(100+(%oppdefence%*5)+1)/32768+1
if %move% equ 2 set /a tauntchance1=(7+(%charisma%*3))
if %move% equ 2 if %tauntchance% leq %tauntchance1% set /a damage=((%charisma%*2)-%RANDOM%*2/32768+1)
if %move% equ 2 set /a energy=%energy%-%charisma%
echo You have %energy%/%maxenergy% energy left.
echo.
echo You dealt %damage% damage.
echo.
pause >nul
Thank you for the responses anyway!
RESOLVED
I found the problem in some variables before in the code and have fixed it, thank you for the help.
set /a tauntchance=%RANDOM%*(100+(%oppdefence%*5))/32768+1
The value of %tauntchance% variable will never be equal to 0. To obtain the desirable result you should use this line
set /a tauntchance=%RANDOM%*(100+(%oppdefence%*5)+1)/32768
There is a problem with the 3rd line also. This part of the code
%random%*1/32768+1
will generate a sequence of 1's only, so the value of %damage% variable will always stay the same. To fix that use %random%*2/32768 instead.
Is that a complete code? Because you either have to initialise your variables first or better yet put them in quotation marks when you use them with if command. The code below runs fine, except that it is meaningless without the proper values of the variables.
#echo off
if "%move%" equ "2" set /a tauntchance=%RANDOM%*(100 + (%oppdefence%*5) + 1)/32768
if "%move%" equ "2" set /a tauntchance1=(7 + (%charisma%*3))
if "%move%" equ "2" if "%tauntchance%" leq "%tauntchance1%" set /a damage=((%charisma%*2) - %RANDOM% %% 2)
if "%move%" equ "2" set /a energy=%energy% - %charisma%
echo You have %energy%/%maxenergy% energy left.
echo.
echo You dealt %damage% damage.
echo.
pause > nul

Batch decimal variable calculator

I am currently working on a game in batch script and in one place, I need to make a multiplication of decimals. The problem is, the end result is always 0.
This is the code:
#echo off
echo Calcultating New Values
echo ...
ping localhost -n 2 >nul
set /p coal_price_buy_brt=<coal_price_buy_brt.wss
set /p coal_ind_buy=<coal_ind_buy.wss
cls
echo First Values :
echo ################################
echo ## Coal Price Brutto ## %coal_price_buy_brt% ##
echo ################################
echo ## Coal Index Buy ## %coal_ind_buy% ##
echo ################################
ping localhost -n 3 >nul
echo %coal_price_buy_brt%
echo %coal_ind_buy%
set ENABLEDELAYEDEXPANSION=coal_price_buy_net
set /p coal_price_buy_net=<calc %coal_price_buy_brt%*%coal_ind_buy%
echo Complete Table :
echo ################################
echo ## Coal Price Brutto ## %coal_price_buy_brt% ##
echo ################################
echo ## Coal Index Buy ## %coal_ind_buy% ##
echo ################################
echo ## Coal Price Netto ## %coal_price_buy_net% ##
echo ################################
The file data are:
coal_price_buy_brt = 150
coal_ind_buy = 0.84
EDIT :
4 years after this post, i'm now in IT Studies and realize that there is a difference between integers and floats in coding...
Thanks for having helped me back then !
The arithmetic operations of SET /A command can only manage integer numbers. Imagine you have a calculator that does NOT have the key for decimal point. How could you achieve this operation: 150*0.84? Well, if you know that the second value is always less than one with two decimals, you may execute 150*84 instead and insert a decimal point before the second digit (from right to left) of the result:
#echo off
set coal_price_buy_brt=150
set coal_ind_buy=0.84
rem Convert coal_ind_buy to integer
set coal_ind_buy=%coal_ind_buy:0.=%
rem Execute the multiplication
set /A result=coal_price_buy_brt*coal_ind_buy
echo Result as integer: %result%
echo Result as fixed point with two decimals: %result:~0,-2%.%result:~-2%
If the values may have integer part, then you may achieve the appropriate conversion to integer values, execute the multiplication, and insert the decimal point in the right place; however, you always must select a fixed number of decimal places ("fixed point arithmetic"), unless you want to convert the values to floating point (with an exponent of ten) and achieve all the apropriate conversions!
For further details about fixed point arithmetic operations in Batch, see: http://www.dostips.com/forum/viewtopic.php?f=3&t=2704&p=12523#p12523
I know this is an older question, but I have had a similar question come up with some scripting of my own. Perhaps my answer can still help someone out there with the same/similar question. My question to myself was, "How can use floating point decimal numbers in my batch script?" After much pondering and researching other personal questions on StackOverflow, I came up with the following example script. It pretty much converts a floating point number into a fraction in the form of two variables that can be used in the rest of your script. It can be used in tandem with this answer https://stackoverflow.com/a/20531384/2464491 to a similar question.
#echo off
setlocal EnableExtensions
setlocal EnableDelayedExpansion
REM This is how I do a block comment.
goto SOF
========Begin Comment========
Title: deciTest.bat
This batch script checks to see if the number inputed is an interger or a floating point number.
If it is a floating point number, it determines to how many decimal places up to 4096 places.
It then informes the user of how to use the floating point number in arithmatic equations.
Of course, if you include within your script, you can simply call upon the !intOut! and
!multiplier! variables elswhere in your script.
=========End Comment=========
:SOF
REM Check to see if the user supplied a number.
if "%1"=="" (
REM If not, tell them how to use the file.
echo Usage: deciTest.bat [number]
echo.
echo [number] The number to check. Enter either an integer
echo or a floating point number.
echo.
goto eof
)
REM Assign the user input to variable decNum
set decNum=%1
REM Plop the number into a file
echo !decNum!>decNum.tmp
REM Check to see if there is a decimal point
findstr /c:"." decNum.tmp >null
REM If it is found, the number is a floating point number
REM So lets make it so we can use it.
if %errorlevel%==0 (
REM Separate our Characteristic (before the .) and Mantissa (after the .)
for /f "tokens=1-18* delims=." %%a in (decNum.tmp) do (
REM Count the length of our Mantissa (How may decimal places?)
set "s=%%b"
set "s=!s!#"
set "decPlaces=0"
for %%P in (4096 2048 1024 512 128 64 32 16 8 4 2 1) do (
if "!s:~%%P,1!" NEQ "" (
set /a "decPlaces+=%%P"
set "s=!S:~%%P!"
)
)
REM Inform the user of our findings.
echo %%a.%%b is a floating point number with !decPlaces! decimal places
call :Integrate
echo.
REM Create the variable !intOUt! for use elswhere in the code
set /a intOut=%%a*!multiple!+%%b
REM Tell the user how to use this particular floating number
echo Your batch file can use !intOut! in your arithmatic equations.
echo Simply divide your result by !multiple!.
)
) else (
REM If it aint floatin', it's an integer
echo %1 is an integer
)
goto eof
:Integrate REM Create the !multiple! variable to be used elsewhere in the script
set count=!decPlaces!
set multiple=1
:startloop
set /a multiple*=10
set /a count-=1
if not !count!==0 goto startloop
:eof
The code demonstrates how to handle floating point numbers. Essentially, it turns floating point numbers into fractions (!intOut!/!multipler!). If you adjust your arithmetic a bit. Multiply by !intOut!, then send !intOut!/!multiplier! with however many decimal places you want to the example script found here: https://stackoverflow.com/a/20531384/2464491
I hope this helps anyone who has run into the same problem when trying to work with floating point numbers in a batch script. Sure it's not designed to work with such numbers, but you can always script your way around the problem.
You can call this batch file to do a mathematical evaluation.
Name it vbs.bat and then use call vbs 150*0.84 and the result will be in a variable called %val%
#echo off
>"%temp%\VBS.vbs" echo Set fso = CreateObject("Scripting.FileSystemObject") : Wscript.echo (%*)
for /f "delims=" %%a in ('cscript /nologo "%temp%\VBS.vbs"') do set "val=%%a"
del "%temp%\VBS.vbs"
Batch mathematics is INTEGER, hence 0.84 will either be interpreted as 0 or as an invalid number.
You may use an hybrid Batch-JScript file as described in this answer: looking for a way to calculate logarithm in a DOS batch file
This method allows you to evaluate any floating point operation, including logarithms, square roots, etc.
#if (#CodeSection == #Batch) #then
#echo off
rem Evaluate floating point expressions via JScript, for example:
call :Expr result=%coal_price_buy_brt%*%coal_ind_buy%
echo %result%
goto :EOF
:Expr result=expression
for /F "delims=" %%a in ('Cscript //nologo //E:JScript "%~F0" "%2"') do set "%1=%%a"
exit /B
#end
WScript.Echo(eval(WScript.Arguments.Unnamed.Item(0)));
For further details on available JScript mathemathic operations, see: http://msdn.microsoft.com/en-us/library/ie/b272f386(v=vs.94).aspx

table==1 was unexpected at this time batch file

I am trying to apply multiple SQL scripts to an Ingres database (using a vnode setup). The testing phase will require it done to four databases. Trying to nip this annoyance in the bud I've started a batch file but receive the error above.
Many of the solutions found suggest that the batch file will evaluate everything within a block when it starts but I cannot see the forest for the trees. I have a suspicion that the parts in :1ST and :2ND are causing the problems but they need to be done.
SQL, Batch and command window output are below
UPDATE core SET sysflag='O'
#ECHO off
SET VN1=dave
SET DB1=dbtest1
SET DB2=dbtest2
SET SQL1=open.sql
SET SQL2=open.sql
:MENU
CLS
ECHO 1 - Leave
ECHO 2 - Database1
ECHO 3 - Database2
SET /P M=Choose then press ENTER:
IF "%M%"=="1" GOTO EOF
IF "%M%"=="2" GOTO 1ST
IF "%M%"=="3" GOTO 2ND
GOTO MENU
:1ST
SET DATABASE=%VN1%::%DB1%
GOTO RUNSQL
:2ND
SET DATABASE=%VN1%::%DB2%
GOTO RUNSQL
:RUNSQL
ECHO Applying SQLs to %DATABASE%
SQL %DATABASE% < %SQL1% > log_%SQL1%.txt
PAUSE
SQL %DATABASE% < %SQL2% > log_%SQL2%.txt
PAUSE
GOTO MENU
:EOF
C:\Users\me\BUILD>IF UPDATE core SET sysflag='O'==1 GOTO EOF
You are expecting the value of %M% to have 1, 2, or 3. But somehow the value is UPDATE core. The IF statement fails because there is a space in the middle of the left value. Token delimiters like space must be escaped, or the entire string on each side should be quoted. You could change your statement to IF "%M%"=="1" GOTO EOF to eliminate the error, but it still will not give the results you want.
The SET /P statement reads the value from stdin. I assume you have not typed the value UPDATE core, but instead your input was either redirected or piped. You are feeding your script the wrong value.
You should add error handling so that the code does not fall through to :1ST if the input is not 1, 2, or 3.
You can explicitly redirect input to the console for your SET /P statement. That way it will ignore the redirected input or piped input that was provided for the batch script.
<con: SET /P "M=Choose then press ENTER: "
But something seems wrong with your whole design. If you are piping or redirecting input for the script, then it doesn't make sense to present an interactive menu of choices in a loop. What happens if the user never presses 1 to quit? Eventually the piped or redirected input will be exhausted, and then you have problems.

How do I request and receive user input in a .bat and use it to run a certain program?

This is what I have so far
#echo off
:Ask
echo Would you like to use developer mode?(Y/N)
set INPUT=
set /P INPUT=Type input: %=%
If %INPUT%=="y" goto yes
If %INPUT%=="n" goto no
If %INPUT%=="Y" goto yes
If %INPUT%=="N" goto no
:yes
java -jar lib/RSBot-4030.jar -dev
echo Starting RSbot in developer mode
:no
java -jar lib/RSBot-4030.jar
echo Starting RSbot in regular mode
pause
Either way if the user enters y or n it always runs in -dev mode.
How do I make it run in -dev mode if the answer is yes, and regular mode if the answer is no. Also, how do I make it ask again if the input isn't Y, N, y, or n?
If the input is, say, N, your IF lines evaluate like this:
If N=="y" goto yes
If N=="n" goto no
…
That is, you are comparing N with "y", then "n" etc. including "N". You are never going to get a match unless the user somehow decides to input "N" or "y" (i.e. either of the four characters, but enclosed in double quotes).
So you need either to remove " from around y, n, Y and N or put them around %INPUT% in your conditional statements. I would recommend the latter, because that way you would be escaping at least some of the characters that have special meaning in batch scripts (if the user managed to type them in). So, this is what you should get:
If "%INPUT%"=="y" goto yes
If "%INPUT%"=="n" goto no
If "%INPUT%"=="Y" goto yes
If "%INPUT%"=="N" goto no
By the way, you could reduce the number of conditions by applying the /I switch to the IF statement, like this:
If /I "%INPUT%"=="y" goto yes
If /I "%INPUT%"=="n" goto no
The /I switch makes the comparisons case-insensitive, and so you don't need separate checks for different-case strings.
One other issue is that, after the development mode command is executed, there's no jumping over the other command, and so, if the user agrees to run Java in the development mode, he'll get it run both in the development mode and the non-development mode. So maybe you need to add something like this to your script:
...
:yes
java -jar lib/RSBot-4030.jar -dev
echo Starting RSbot in developer mode
goto cont
:no
java -jar lib/RSBot-4030.jar
echo Starting RSbot in regular mode
:cont
pause
Finally, to address the issue of processing incorrect input, you could simply add another (unconditional) goto command just after the conditional statements, just before the yes label, namely goto Ask, to return to the beginning of your script where the prompt is displayed and the input is requested, or you could also add another ECHO command before the jump, explaining that the input was incorrect, something like this:
#echo off
:Ask
echo Would you like to use developer mode?(Y/N)
set INPUT=
set /P INPUT=Type input: %=%
If /I "%INPUT%"=="y" goto yes
If /I "%INPUT%"=="n" goto no
echo Incorrect input & goto Ask
:yes
...
Note: Some of the issues mentioned here have also been addressed by #xmjx in their answer, which I fully acknowledge.
i just do :
set /p input= yes or no
if %input%==yes echo you clicked yes
if %input%==no echo you clicked no
pause
Here is a working example:
#echo off
:ask
#echo echo Would you like to use developer mode?(Y/N)
set INPUT=
set /P INPUT=Type input: %=%
If /I "%INPUT%"=="y" goto yes
If /I "%INPUT%"=="n" goto no
goto ask
:yes
#echo you select yes
goto exit
:no
#echo you select no
goto exit
:exit
#pause
I have improved batch file with yes or no prompt. If user enter any character except y and n , then it will again prompt user for valid input. It Works for me.
#echo off
:ConfirmBox
set /P c= Are you sure want to contine (y/n)?
if /I "%c%" EQU "Y" (
goto :FnYes
) else if /I "%c%" EQU "N" (
goto :FnNo
) else (
goto :InValid
)
:FnYes
echo You have entered Y
goto :END
:FnNo
echo You have entered N
goto :END
:InValid
echo Invalid selection. Enter Y or N
goto :ConfirmBox
:END
pause
exit
/I in if condition will validate both lowercase and uppercase characters.
echo off
setlocal
SET AREYOUSURE = N
:PROMPT
set /P AREYOUSURE=Update Release Files (Y/N)?
if /I %AREYOUSURE% NEQ Y GOTO END
set /P AREYOUSURE=Are You Sure you want to Update Release Files (Y/N)?
if /I %AREYOUSURE% NEQ Y GOTO END
echo Copying New Files
:END
This is code I use regularly. I have noticed in the examples in this blog that quotes are used. If the test line is changed to use quotes the test is invalid.
if /I %AREYOUSURE% NEQ "Y" GOTO END
I have tested on XP, Vista, Win7 and Win8. All fail when quotes are used.
I don't know the platform you're doing this on but I assume Windows due to the .bat extension.
Also I don't have a way to check this but this seems like the batch processor skips the If lines due to some errors and then executes the one with -dev.
You could try this by chaning the two jump targets (:yes and :no) along with the code. If then the line without -dev is executed you know your If lines are erroneous.
If so, please check if == is really the right way to do a comparison in .bat files.
Also, judging from the way bash does this stuff, %foo=="y" might evaluate to true only if %foo includes the quotes. So maybe "%foo"=="y" is the way to go.
Depending on the version of Windows you might find the use of the "Choice" option to be helpful. It is not supported in most if not all x64 versions as far as I can tell.
A handy substitution called Choice.vbs along with examples of use can be found on SourceForge under the name Choice.zip
Add quotation marks (" ") around the %INPUT% so it looks like this:
If "%INPUT%" == "y" goto yes
If "%INPUT%" == "n" goto no
If "%INPUT%" == "Y" goto yes
If "%INPUT%" == "N" goto no
try this for comparision
if "%INPUT%"=="y"...

Batch Script SET /p without a value

Creating a batch script in Windows XP. Here's a snippet of code I'm having problems with:
::==============================================================::
::How many scripts are included in this program?
SET NumOfScripts=4
::==============================================================::
:mainmenu
CLS
ECHO [MAIN MENU]
ECHO Please choose from the following options to run a particular script:
set /p choice="[1] SCRIPT1.bat | [2] SCRIPT2.bat | [3] SCRIPT3.bat | [4] SCRIPT4.bat : "
IF %choice% EQU 1 CALL :SCRIPT1
IF %choice% EQU 2 CALL :SCRIPT2
IF %choice% EQU 3 CALL :SCRIPT3
IF %choice% EQU 4 CALL :SCRIPT4
REM Wrong Choices
IF %choice% GTR %NumOfScripts% (
(ECHO You have entered an invalid option. Please press any key to be taken back to the main menu.) & PAUSE & GOTO:mainmenu
)
IF %choice% LEQ 0 (
(ECHO You have entered an invalid option. Please press any key to be taken back to the main menu.) & PAUSE & GOTO:mainmenu
)
ECHO You have entered an invalid option. Please press any key to be taken back to the main menu
PAUSE & GOTO:mainmenu
Looking under REM Wrong Choice, the first two arguments work as they should, however, if the user enters in no value (just presses the enter key) it automatically terminates the script. I've added IF NOT DEFINED choice and that doesn't work... I also tried IF [%choice%]==[] and IF [%choice%] EQU [] and those don't work either.
Here's the funny thing... you enter an invalid digit, say 5 or -1, it will give the echoes and go back to the main menu as it should... THEN if you just press enter without a value inserted, it will echo and go back to the main menu as it should.
My question is how do you get it to recognize that the user did not enter a value for set /p on the first go?
You can initialize choice to some invalid value before set /p, e.g.:
SET choice=none
To print the appropriate error message, you can do
IF %choice% EQU none (
(ECHO You did not select an option.) & PAUSE & GOTO:mainmenu
)
Set /p doesn't change the content of a variable, if the user doesn't enter text.
So you can simply set your variable to nothing to detect if the user enter anything.
Set "choice="
Or you can use the errorlevel, as it is set to 1 if the input is empty
But be careful, as it doesn't reset it to 0. So you have to force it yourself before.
cd.
Set /p choose=
If %errorlevel%==1 goto empty
And you should use the variables with delayed expansion, as it is always safe.
Else a user can break your script with input like "&exit"