Reputation: 35
This is my first time trying scripting and I'm trying to create a small program that does a simple division and mod in a loop, and then calculates the average of the mod results. This is what I have tried in Linux .sh, but how could I make it compatible with Windows .bat? Your help is very appreciated.
echo "enter first number:"
read first_num
echo “enter second number:”
read second_num
while [ first_num && second_num != 999 ]
do
if [ second_num != 0 ]; then
echo "Enter first number:"
read first_num
echo"Enter second number:"
read second_num
echo first_num "/" second_num "=" $((first_num / second_ num)) >> file.txt
else
echo "ERROR. Cannot divide by 0. Enter another number:"
fi
done
if [ first_num == 999 || second_num == 999 ]; then
echo "You have exited the loop."
fi
#Mod 5 of numbers 1-100:
for i in {1...100}
do
result=$((i % 5))
echo i + "%5=" + result >> file.txt
done
#Average of results:
int sum=0
for (( i=1; i<101; i=i+1 ))
do
sum=sum+$((i % 5))
average=$((sum/100))
echo average
echo average >> file.txt
done
Upvotes: 0
Views: 302
Reputation: 167
Hope you're looking for this:
@echo off
setlocal enabledelayedexpansion
> file.txt type nul
:loopInput
echo enter first number:
set /p first_num=
echo enter second number:
set /p second_num=
if !first_num! neq 0 (
if !second_num! neq 999 (
if !second_num! equ 0 (
echo ERROR. Cannot divide by 0. Enter another number:
goto loopInput
)
goto loopDiv
)
)
goto :skipDiv
:loopDiv
set /a division=first_num/second_num
>> file.txt echo !first_num! / !second_num! = !division!
goto loopInput
:skipDiv
echo You have exited the div loop.
>> file.txt echo Mod 5 of numbers 1-100:
for /l %%a in (1,1,100) do (
set /a mod=%%a%%5
>> file.txt echo %%a %% 5 = !mod!
)
set sum=0
for /l %%a in (1,1,100) do (
set /a sum+=%%a%%5
)
set /a average=sum/100
>> file.txt echo Average of results: !average!
Upvotes: 0
Reputation: 80023
echo "enter first number:"
read first_num
becomes set /p first_num="Enter first number "
while [ first_num && second_num != 999 ]
don't have a WHILE - have to wire it. Think clubs and rocks.
:loop
if %first_num%==999 goto endloop
if %second_num%==999 goto endloop
...
goto loop
:endloop
:name
is a label, %var%
retrieves contents of var
- is always a string enclose in quotes if the string includes spaces.
if [ second_num != 0 ]; then
translated is
if NOT %second_num%==0 ( ...things... ) else (...other things...)
or, of course
if %second_num%==0 ( ...other things... ) else (...things...)
Quirk: (one of many) : the first open-parenthesis MUST occur on the same physical line as the IF
and the ELSE
must be on the same physical line as the )
of the on-true statemet sequence.
echo first_num "/" second_num "=" $((first_num / second_ num)) >> file.txt
Can't do a calculation in an echo
set /a result=(first_num / second_ num)
OR
set /a result=(%first_num% / %second_ num%)
SET /A
applies the results of an arithmetic expression - later addition and more C-like semantics
then
echo %first_num% / %second_num% = %result% >> file.txt
purely stringing the elements together.
Next there is a small problem. During the parsing process, any %var% is replaced by its PARSE-TIME value and THEN the line is executed. Consequently, the ECHO
line above would show the values as they stood when the IF statement was entered, not after the calculations.
Two cures:
You can use SETLOCAL ENABLEDELATEDEXPANSION
to switch the interpreter mode. In DELAYEDEXPANSION mode, !var!
may be used to retrieve the RUN-TIME value of var
. A SETLOCAL
is terminated by an ENDLOCAL
or by reaching END-OF-FILE in the same context. Any environment changes after a SETLOCAL
are undone by an ENDLOCAL
which is why it's often performed immediately after the @echo off
- keeps the environment clean.
second cure is to use a subroutine. CALL :SUB
(the colon means 'internal subroutine - start label is in this batchfile'. Omitting it means 'this is an external executable') The CALL creates a new context, copying the then-existing environment variables, so
:sub
echo %first_num% / %second_num% = %result% >> file.txt
goto :eof
will display the variables from the environment as it stood when a CALL :SUB
was executed.
Note that GOTO :EOF
(the colon is REQUIRED
means 'go to physical end-of-file' - the label EOF
should not be declared...
(beware also flow-through to subroutines normally placed at the end of batchfiles. A judicious GOTO :EOF
ensures that flow-through does not occur...
#Mod 5 of numbers 1-100:
The comments indicator is officially REM
rem Mod 5 of numbers 1-100:
BUT
::Mod 5 of numbers 1-100:
is often used as it's easier to type BUT since it's actually a misuse of a label, it is actually a label, and labels can't be used in a compound statement, you you can't use it within the parentheses of IF ... (...) else (...)
or FOR...DO (...)
for i in {1...100}
becomes
for /L %%i in (1,1,100) do (
The metavariable %%i
IS case-sensitive and a single character. in a FOR /L
the elements are (start,step,end) - see FOR /?
from the prompt (or generally command /?
from the prompt) for docco...
result=$((i % 5))
becomes
set /a result=%%i %% 5
/a
because the RHS is an arithmetic expression to be evaluated; %% 5 because %
escapes %
, the space is irrelevant and the processor needs to know that the MOD operator %
is being used, not %5
(the fifth command-line argument)
int sum=0
No such thing as types; all environment variables are strings and only interpreted as integers by the set /a
statement
so - that's about all there is to it...
Upvotes: 3