Everything works fine in this program except when user enters the correct number generated by the program. For example, it replies "too low" if you enter 13, and "too high" if you enter 14. How do you fix this so the 3rd if statement functions properly?
#echo off
title Game
set num1=%random%%101
:start
set /p num2=Enter a number:
if %num2% gtr %num1% (echo too high
pause
cls
goto :start
)
if %num2% lss %num1% (echo too low
pause
cls
goto :start
)
if %num2% equ %num1% (echo Bingo!)
pause
cls
exit
This batch file works fine:
#echo off
title Game
setlocal EnableDelayedExpansion
set /A num1=%random% %% 101
:Retry
cls
set "num2="
set /P "num2=Enter a number (%num1%): "
if !num2! GTR %num1% (
echo too high
pause
goto Retry
)
if !num2! LSS %num1% (
echo too low
pause
goto Retry
)
if !num2! EQU %num1% (
endlocal
echo Bingo!
pause
exit /B
)
goto Retry
The line
set num1=%random%%101
could be also used in the batch file above, but creates
a number with a random part and
appended the first argument passed to the batch file if called with a parameter at all and
appended the digits 0 and 1.
I suppose like SomethingDark that a random number between 0 and 100 is wanted here.
start is a standard Windows command and therefore it is advisable not to use start as label although possible.
Delayed expansion is enabled and used for num2 to avoid an exit of the batch file caused by a syntax error when the batch user enters nothing or by mistake not a number.
Also the environment variable num2 is always unset before prompting the user as otherwise the batch user could just hit RETURN or ENTER to continue with whatever variable num2 currently has as value.
Note: The random number is output in prompt text to see what to enter for testing.
Related
I have made a list of names of which I wish to choose with several numbers, and the do loop confirms these numbers. But for some reason I cannot get these chosen numbers aligned to the GOTO echo statement. Instead they just list them all? I have to admit I am new to batch scripting but I'm sure there is an abundance of experts who can see where I am going wrong, pls pls help me?
The code i have is here along with the output I get in command prompt
:START
setlocal EnableDelayedExpansion
#echo OFF
echo. [RUN BVTS]
ECHO 1.RS_CommonDataSet
ECHO 2.RS03_PackageManager
ECHO 3.RS04_SequencerCalendars
ECHO 4.RS06_EditorTestsPerformance
ECHO 5.RS06_NewEditorTests
ECHO OFF
set /p BVTSUITE="What BVT suite do you wish to run? "
rem This lists all the BVT's that you want to run with spaces
set n=0
for %%a in (%BVTSUITE%) do (
set /A n+=1
set "BVTSUITE[!n!]=%%~a"
)
rem List the file names
for /L %%i in (1,1,%n%) do (
echo %%i- !BVTSUITE[%%i]!
)
IF %errorlevel%==1 set goto 1
:1
ECHO "You have chosen number RS_CommonDataSet"
IF %errorlevel%==2 set goto 2
:2
ECHO "You have chosen number RS03_PackageManager"
IF %errorlevel%==3 set goto 3
:3
ECHO "You have chosen number RS04_SequencerCalendars"
IF %errorlevel%==4 set goto 4
:4
ECHO "You have chosen number RS06_EditorTestsPerformance"
IF %errorlevel%==5 set goto 5
:5
ECHO "You have chosen number RS06_NewEditorTests"
The output I get in command prompt is:
[RUN BVTS]
1.RS_CommonDataSet
2.RS03_PackageManager
3.RS04_SequencerCalendars
4.RS06_EditorTestsPerformance
5.RS06_NewEditorTests
What BVT suite do you wish to run? 1 3 (I chose these numbers)
1- 1
2- 3
"You have chosen number RS_CommonDataSet"
"You have chosen number RS03_PackageManager"
"You have chosen number RS04_SequencerCalendars"
"You have chosen number RS06_EditorTestsPerformance"
"You have chosen number RS06_NewEditorTests"
As you can see my 1 and 3 was chosen but it is not in the ouput, it just shows the entire list?
I've added comments to the parts that I've added, but basically, your entire script runs because you never told it not to. Batch scripts are just a list of commands and the order to run them in, so unless you use a goto, a call, or an exit, each line will run one after the next.
If you use subroutines, you'll be able to control which parts of the script get executed. I've also added super rudimentary input validation because sooner or later, the user will enter something incorrectly. It's not foolproof, but it's good enough that I'm comfortable posting it.
#echo off
setlocal EnableDelayedExpansion
echo. [RUN BVTS]
echo 1.RS_CommonDataSet
echo 2.RS03_PackageManager
echo 3.RS04_SequencerCalendars
echo 4.RS06_EditorTestsPerformance
echo 5.RS06_NewEditorTests
:get_suite_list
set /p "BVTSUITE=What BVT suite do you wish to run? "
rem This lists all the BVTs that you want to run with spaces
if not defined BVTSUITE goto :get_suite_list
set n=0
for %%a in (%BVTSUITE%) do (
set /A n+=1
set "BVTSUITE[!n!]=%%~a"
)
REM List the file names
for /L %%i in (1,1,%n%) do (
echo %%i - !BVTSUITE[%%i]!
REM Double-check that all given BVT suites are valid and the user didn't
REM provide an invalid value like 7 or Q or something
find ":suite_!BVTSUITE[%%i]!" "%~f0" >nul 2>nul || (
echo Invalid suite !BVTSUITE[%%i]! given.
goto :get_suite_list
)
)
REM Actually call the different suites.
for /L %%i in (1,1,%n%) do (
call :suite_!BVTSUITE[%%i]!
)
REM At this point, the main script ends and returns to the command prompt
exit /b
REM These are subroutines. You'll never be able to reach them unless you use
REM the CALL command to tell cmd to jump to here, and then once the exit /b
REM command is executed, flow returns to where it was when CALL was executed.
REM Also, I've prepended the string suite_ in front of each label because
REM having a single number as a label is a terrible idea since it's absolutely
REM meaningless.
:suite_1
echo You have chosen number RS_CommonDataSet
exit /b
:suite_2
echo You have chosen number RS03_PackageManager
exit /b
:suite_3
echo You have chosen number RS04_SequencerCalendars
exit /b
:suite_4
echo You have chosen number RS06_EditorTestsPerformance
exit /b
:suite_5
echo You have chosen number RS06_NewEditorTests
exit /b
You don't need to identify each file name via the given suite individually. Just define an array of file names and select the appropiate element via the given value:
#echo OFF
setlocal EnableDelayedExpansion
rem Define array with the names of the suites
set numSuites=0
for %%a in (RS_CommonDataSet RS03_PackageManager RS04_SequencerCalendars RS06_EditorTestsPerformance RS06_NewEditorTests) do (
set /A numSuites+=1
set "BVTNAME[!numSuites!]=%%a"
)
rem Show the menu
echo [RUN BVTS]
echo/
for /L %%i in (1,1,%numSuites%) do (
echo %%i.!BVTNAME[%%i]!
)
echo/
set /p "BVTSUITE=What BVT suite do you wish to run? "
rem This lists all the BVT's that you want to run with spaces (and file names)
set n=0
for %%i in (%BVTSUITE%) do (
set /A n+=1
if defined BVTNAME[%%i] (
echo !n!- %%i.!BVTNAME[%%i]!
) else (
echo !n!- Invalid suite: %%i
)
)
(This is my first post here, so bear with me)
Can you show the last user-input in a batch file? I'm gonna try to keep it simple here.
#echo off
:menu
echo Type 1 to proceed.
set /p example=
if "%example%" == "1" GOTO :proceed
GOTO :error
:proceed
pause
:error
cls
echo You wrote (last user input), that's not correct.
timeout 30
GOTO :menu
I know that I could replace the (last user input) with %example%, but then I'd have to make custom error messages for every category, and there are about 50 of them. It'd be easier with a last input command.
By the way, I've taught myself everything that I know about batch, so my example probably has major issues right now, but it works somehow.
You could centralize all user input into a function (user_input)
:menu1
echo Type 1 to proceed.
call :userInput example
if "%example%" == "1" GOTO :proceed
GOTO :error
:menu2
echo Type 42 to proceed.
call :userInput answer
if "%answer%" == "42" GOTO :proceed
GOTO :error
:userInput
set /p LAST_INPUT=
set "%1=%LAST_INPUT%"
exit /b
:proceed
pause
:error
cls
echo You wrote "%LAST_INPUT%", that's not correct.
timeout 30
GOTO :menu
I don't know how to do it without temp file. TO get the things written int the console you need the doskey /history (this will skip the running of the script itself):
#echo off
setlocal enableDelayedExpansion
set "last="
set "but_last="
doskey /history > log.txt
for /f "tokens=* delims=" %%# in (log.txt) do (
set "but_last=!last!"
set "last=%%#"
)
echo "%but_last%"
del /s /q log.txt >nul 2>nul
I'm currently trying to write a batch program that takes in two numbers that the user inputs. I had to create an exit number for the user if they choose to exit the program by entering the number 22. If the user doesn't exit the program it goes to check that the second number entered isn't 0. If it is 0 the user has to reenter another number and then proceed to divide the first number by the second number and display it.
My current issue is that if the user enters a correct value for both variables it still requests the user to another number for the secondNum. The program is supposed to continue running until the user enters the exit number 22. As for the display I don't want to only display the out put but rather this: 10 divided by 2 = 5.
#echo off
title lodiDpgm4
echo resulst.txt
echo Daniel Lodi >> results.txt
set datet=%date:~-7,2%-%date:~-10,2%-%date:~-4,4% %time:~0,2%:%time:~3,2%:%time:~6,2%
echo %datet% >> results.txt
setlocal enabledelayedexpansion
:main
cls
set /p firstNum="Enter your first number"
if !firstNum! == 22 goto :eof
set /p secondNum="Enter your second number"
if !secondNum! == 22 goto :eof
if "%secondNum%"=="0" goto :loop
goto :calculate
:loop
set /p "secondNum=You can not divide by 0 please enter another number"
if "%secondNum%"=="0" goto :loop
pause
:calculate
#echo off
set /a results=(firstNum/secondNum)
echo %results%
pause
goto :main
:eof
cls
#echo off
echo.
echo.
echo. Promgram has ended, thank you.
Why does this batch code not work?
I certainly don't know why...
Download: http://tufda.net/downloads/explore/StackOverflow%20files/ultraworld.bat
#echo on
cls
set game=UltraWorld
echo Welcome to %game%!
PAUSE
cls
echo What's your name?:
set /p playername=""
cls
echo Welcome to %game%, %playername%!
PAUSE
:titlescreen
cls
echo Commands:
echo new
echo load
echo credits
echo.
set /p command1=Enter your command here:
IF command1==new (
set /p gamesave1=What name will you give this save?
)
IF command1==load (
echo No.
PAUSE
goto titlescreen
)
IF command1=="credits" (echo Everything - tufda & PAUSE & goto titlescreen)
PAUSE
When you test the variable, you need to either surround it in percentage marks, or surround it with exclamation marks, if
setlocal enabledelayedexpansion
is used.
For example,
IF %command1%==load (
When using the IF command in a batch file, you need to follow the proper syntax.
The correct way to write an IF command is:
IF /I "%command1%" EQU "new" (
The Quotes arround each side will account for an empty value, while the EQU is the comarison type which is equivelant to ==. The comparisons are as follows:
EQU - equal
NEQ - not equal
LSS - less than
LEQ - less than or equal
GTR - greater than
GEQ - greater than or equal
I used a /I to indicate that the comparison is not case sensitive.
I'm working on a program to backup Fallout 4 Saves, because using console commands can bork a save file this time around. Unfortuanly, while all of the parts are working independently, the little menu I have made isn't working!
For some reason the if %1m% == _ goto _ commands are doing nothing, and the program skips back to the label 1, a feature I put there in case of invalid input.
What's wrong here?
#echo off
title Fallout 4 Save Backup Utility
color 0a
:1
cls
setLocal EnableDelayedExpansion
pushd "C:\FalloutBackup\data\"
set /a count=0
for /d /r %%i in (*.*) do set /a count+=1
popd
echo %count% Backup(s^) currently exist.
echo.
echo.
set /a value=0
set /a sum=0
FOR /R %1 %%I IN (*) DO (
set /a value=%%~zI/1000000
set /a sum=!sum!+!value!
)
#echo Backups files using about: !sum! Mb
endlocal
echo.
echo.
echo Delete all but last backup? y/n?
set /p 1m=
if %1m% == y goto 3
if %1m% == Y goto 3
if %1m% == n goto 2
if %1m% == N goto 2
cls
goto 1
As Squash man Said:
Change your variable 1m to m1. CMD interpreter is not smart enough to know that you are trying to reference an environmental variable and not a argument passed to the batch file. –
I also recommend using quotes for the "%m1%"=="y". Also, the /I parameter after IF makes the answer not cap-sensitive, a big plus.
Another option would be to use CHOICE and ERRORLEVEL for option selection. The relevant code changes would be:
echo.
choice /c yn /m "Delete all but last backup? "
IF ERRORLEVEL 255 goto end
IF ERRORLEVEL 2 goto donotdelete
IF ERRORLEVEL 1 goto dodelete
IF ERRORLEVEL 0 goto end
goto begin
(255 and 0 are there for escapes.)
(You will need to obtain the choice COM file, which is readily available.)