Batch program | Loop breaks, and output display - loops

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.

Related

Why does my errorlevels don't list my echo messages in my batch script? They just list them all

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

Why does my program in batch give me the wrong number when i times 2 numbers?

When i execute my program and put in something like 1280000000*20 it gives me -169803776 when it should be 25600000000, when i then try 25600000000/20 it gives me -1698037766 which is different. This shows there is something wrong with my calculator because the laws of maths say when a*b=c, b/c=a which isnt true in this situation. The calculations are also incorrect.
I've tried putting the same code into python (different language) and it works fine so i think its something to do with batch itself.
echo off
cls
:start
cls
echo Welcome to the calculator
echo.
echo Choose one of the of the following
echo.
echo 1. Multiplication
echo 2. Division
echo.
set /p choose=Choose a number:
IF %choose%==1 (
goto multiply
) ELSE IF %choose%==2 (
goto divide
) ELSE (
goto error
)
:error
cls
echo THAT ISNT AN OPTION!!
echo.
pause
goto start
:multiply
cls
echo Pick 2 numbers to multiply
echo.
set /p a=Number 1:
set /p b=Number 2:
set /a c=%a%*%b%
cls
echo %a% x %b% = %c%
pause
goto start
:divide
cls
echo Pick 2 numbers to divide
echo.
set /p a=Number 1:
set /p b=Number 2:
set /a c=%a%/%b%
cls
echo %a% / %b% = %c%
pause
goto start
I expect the output of 1280000000*20=25600000000, but the actual output is -169803776. This number changes every time to a negative for some reason.

How do I create an update function in Batch?

I would like to create an update function that works just after the user is prompted to type into the "ChatBox" so that other users on my school network can type and all other users can see it without having to restart the program or typing space to reload the .txt file
here is the code I have written so far;
:enter
cls
type cblog.txt
echo.
set /p text=
echo %text% >> cblog.txt
goto enter
I like this topic, so I wrote a fully working prototype:
#echo off
setlocal
if "%~1" equ "" echo You must give your username as parameter & goto :EOF
set "user=%~1"
set "now=%time%"
echo %now%: User %user% entered the chat room>> msgQueue.txt
call :chatRoom 3< msgQueue.txt
goto :EOF
:chatRoom
rem Omit previous messages
:omitMsg
set /P "msg=" <&3
if "%msg:~0,12%" neq "%now%:" goto omitMsg
echo %msg%
echo/
echo Press S to send a message or eXit to end
echo/
:msgLoop
rem Check for new messages received
:showMsg
set "msg="
set /P "msg=" <&3
if not defined msg goto send
echo %msg%
goto :showMsg
rem Check to send a new message
:send
ver > NUL
choice /C SNX /N /T 3 /D N > NUL
if errorlevel 3 goto end
if errorlevel 2 goto msgLoop
rem Send a message
echo -----------------------------------
set /P "msg=Message: "
echo -----------------------------------
echo %user%: %msg% >> msgQueue.txt
goto msgLoop
:end
echo %time%: User %user% leaved the chat room>> msgQueue.txt
The response time may be adjusted in /T 3 parameter of choice command: shorter times makes the chat more responsive, but it consume more CPU time.
Below is an image that show a test with four users in the Chat Room:

How to set the EQU operator to work properly?

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.

Programming set /p input

I have two scripts. First script is asking user for some input and calling another script giving it the input as a parameter. Second script is again asking user for the same input.
first.bat
set /p input=Insert your input:
call second.bat %input%
second.bat
if %1 == "Y" input=%1 & goto skipInput
set /p input=Insert the same input:
:skipInput
echo Skipped user input
Is it possible to set second user input with first input value without user pressing the same input value? Problem is that set /p in second.bat cannot be skipped like in upper example.
Updated solution:
first.bat
set /p input=Insert your input:
echo %input% | (cd path/to/file & second.bat)
echo %input% | (cd path/to/file & second.bat)
pause >nul
I'm not 100% sure what you are trying to do, but maybe this
First.bat
set /p input=Insert your input:
call second.bat %input%
Second.bat
if %1=="Y" set input=%1
Which will set the variable input in the second script to the value of input in the first script.
Update
If you only have access to the initial batch that calls the others then try this
#echo off
set /p input=Insert your input:
echo %input%| second.bat
pause >nul
After running that I managed to get the prompt in the second batch which just has the set /p line to be filled in using the pipe redirection.
:first.bat
cls
set /p input=Enter input.
if "%input%" equ "" goto first.bat
call seccond.bat %input%
What happens here is if the user's input is equal to "NUL" go back to the beginning.
:seccond.bat
cls
set input=%*
if /i "%input%" equ "Y" do command
Put your code below for SECCOND.bat

Resources