:teattack1
set /a health-=!monsterdmg! # It said missing operator here
pause
set /a monsterhealth-=!playerdmg! # And Here
pause
if "!monsterhealth!" == lss 0 goto tewin
pause
goto testencounter
pause
goto encountermenu
I keep getting Missing Operator
I serched how to fix it but did not find anything
You need to add:
Setlocal EnableDelayedExpansion
to your script to allow the use of !
Check here for an overview of what this does and why its needed
Open a command prompt window, enter set /? and read all output help pages carefully.
It is explained that when using set for an arithmetic expression, i.e. set /A, then variable names can be specified directly without expansion. Windows command processor interprets automatically each string not being a number or an operator as name of a variable and access the current variable value on evaluating the arithmetic expression.
Next run in command prompt window if /? and read again all output help pages carefully.
The line
if "!monsterhealth!" == lss 0 goto tewin
is definitely invalid as it contains the operator == and the operator lss which of course can't work.
This improved code is with all coding mistakes fixed.
:teattack1
set /a health-=monsterdmg
pause
set /a monsterhealth-=playerdmg
pause
if %monsterhealth% LEQ 0 goto tewin
pause
goto testencounter
pause
goto encountermenu
However, the environment variables health, monsterdmg, monsterhealth and playerdmg should all exist and have an integer value assigned as otherwise Windows command interpreter uses value 0 for each variable making the code not really useful.
Related
My batch script is written for measuring how much traffic between two PCs a network can handle. So the script determines the size of a file and send it from one PC to another and count how many times this works. But there is a weird problem on the calculation of total number of successfully transfered bytes. The value of environment variable asdf3 printed via echo after the calculation seems to be inaccurate.
echo hat %count% mal geklappt
echo size: %menge% byte
set /a asdf3=%count%*%menge%
echo es wurden %asdf3% byte verschoben
The lines above produce this output:
hat 58 mal geklappt
size: 30245 byte
es wurden 2722050 byte verschoben
It should be 1754210 (58 * 30245) if my math is okay.
The variables are initialized like this:
set file="test.odt"
FOR /F "usebackq" %%A IN ('%file%') DO set /A menge=%%~zA
set /A count=0
:marker
COPY /Y /V %file% \\%name%\Users\public
if 0==%errorlevel% (
set/Acount=%count%+1
goto :marker
)
Why does evaluation of the simple arithmetic expression in batch file produce 2722050 instead of expected result 1754210?
Do not use the syntax set variable="value". It is better to use the syntax set "variable=value" and reference the environment variable value as is or concatenated with a fixed string or another environment variable reference enclosed in double quotes. Please take also a look on answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? It explains with even more details why it is better to use set "variable=value" with first " left to variable name.
Do not use for /F designed for processing a text file line by line, a string or captured output of a command line to just get a property of a file.
Do not use set /A which results in interpreting the rest of the line as an arithmetic expression to just define an environment variable which is always of type string in memory with a value.
The loop runs endless as long as copying the file is successful. Is that really wanted?
Avoid usage of %errorlevel% with command IF as there is the syntax if errorlevel X for testing if exit code of previous command or application is greater or equal X or if not errorlevel X for testing if exit code of previous command is lower than X which means usually equal 0 as commands and applications do not exist with a negative value.
There is a space character missing between set and /A and one more between /A and count=%count%+1.
The help output on running set /? in a command prompt window explains for set /A that environment variables can be referenced within an arithmetic expression with just their name without % or ! around as long as the environment variable name does not contain an arithmetic operator, a delimiter like a space or a comma and can't be mistakenly interpreted as integer number.
Windows command processor uses 32-bit signed integer arithmetic and so the value range -2147483648 to +2147483647. This means in combination with file size that the value range is limited to 2 GiB before a not handled or reported overflow occurs on evaluation of the arithmetic expression resulting nearly always in unexpected results. For more details see: weird results with IF
There is no need to specify on GOTO command line the label with colon at beginning except for special label :EOF. For details see Where does GOTO :EOF return to?
Here is your code rewritten with no extra code to work around the 32-bit signed integer limitation.
set "name=127.0.0.1"
set "file=test.odt"
for %%A in ("%file%") do set "menge=%%~zA"
set "count=0"
:marker
if %count% == 100 goto Output
COPY /Y /V "%file%" "\\%name%\Users\public"
if not errorlevel 1 set /A "count+=1" & goto marker
:Output
echo hat %count% mal geklappt
echo size: %menge% bytes
set /A asdf3=count * menge
echo es wurden %asdf3% bytes verschoben
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
copy /?
echo /?
for /?
goto /?
if /?
set /?
See also Single line with multiple commands using Windows batch file for an explanation of operator &.
I seem to have a problem with my "if" statements. Currently after the pause in "start" the file just closes and nothing else happens. Chances are, I have no idea what I'm doing.
#echo off
set startnum=0
goto start
:start
pause
set startnum="!startnum!"+1
if "%startnum%"="%0%" goto fail
if "%startnum%"="%1%" goto success
goto start
:success
cls
echo It worked!
echo "%startnum%"
pause.
exit
:fail
cls
echo Failure
pause.
exit
First problem:
set startnum="!startnum!"+1
Evidently, you wish to add 1 to startnum.
Your set command would set startnum to "!startnum!"+1. Literally. To perform arithmetic, you need set /a.
set /A startnum="!startnum!"+1
well, this won't work as "!startnum! isn't numeric. Had you invoked delayedexpansion beforehand, then the value of startnum would have been substituted for !startnum! yielding set /A startnum="0"+1 which makes more, but still not much sense.
set /A startnum=startnum+1
adds 1 to startnum - see set /? from the prompt for documentation.
set /A startnum+=1
would also add 1 to startnum.
Next problem.
if "%startnum%"="%0%" goto fail
Well, you appear to have found lss and all that gang. Problem is that the simple comparison operator is ==, not =.
if "%startnum%"=="%0%" goto fail
Now - what will that do? It will compare "thecontentsofstartnum" to "thecontentsof0". Since both of these arguments are quoted, batch will perform a string comparison. With a string comparison, 123 is less than 89 because 1 is less than 8.
But - you are attempting an equivalence comparison (equ as the operator may be used instead of ==) so the preceding point is simply AAMOI.
The difficulty is %0% which you may believe attempts to extract the value of the variable 0 but actually it replaces %0 with the value of the 0th parameter to the batchfile, which is the batchfile name itself, so you get "batchfilename%" - probably not what you actually wanted.
if "%startnum%"=="0" goto fail
is the way to implement that test.
The first IF statement is preprocessed by cmd.exe to
if ""!startnum!"+1"="test.bat" goto fail
which is a completely invalid IF condition.
cmd.exe outputs a syntax error message because of "="test.bat"" and exits batch file processing. This can be seen by debugging the batch file.
The solution is using right syntax for
assigning a value to an environment variable,
an arithmetic expression,
and last but not least the IF condition itself.
The batch file code fixed:
#echo off
set "startnum=0"
goto Begin
:Begin
set /A startnum+=1
if "%startnum%" == "0" goto Fail
if "%startnum%" == "1" goto Success
goto Begin
:Success
cls
echo It worked!
echo "%startnum%"
pause
exit /B
:Fail
cls
echo Failure
pause
exit /B
It would be safe here to remove all double quotes on both IF conditions.
One more hint: Don't use the name of a command like START as label. It works, but it should be avoided in case of ever adding to batch file the command START and searching for either command or label.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
call /? ... explains how to reference batch file arguments.
cls /?
echo /?
exit /?
goto /?
if /?
pause /?
set /?
Further read the answers on following questions:
Batch file comparison of variable with constant fails
Why is no string output with 'echo %var%' after using 'set var = text' on command line?
Where does GOTO :EOF return to?
Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files
This question already has an answer here:
Variables are not behaving as expected
(1 answer)
Closed 5 years ago.
The variables _dd and _mm hold current day and month. 3 must be added to current day and if the day is greater than 27, 1 must be added to month (to change it to a month ahead).
Set /A _dd=%_dd%+3
REM **Set /A _mm=%_mm%+1**
echo %_dd%
IF %_dd% LSS 10 Set _dd=0%_dd%
IF %_dd% GTR 27 (
Set _dd=01
Set /A _mm=%_mm%+1
Set _mm=0%_mm%
Echo !_mm%! )
Set /A _mm=%_mm%+1 is working when ran outside IF statement, but not in action of IF statement.
Why is SET /A command line not working as expected after IF statement?
All occurrences of %_mm% are replaced during preprocessing the entire command block starting with ( and ending with matching ) before the IF condition is executed at all by Windows command interpreter. This behavior can be seen by running the batch file from within a command prompt window without #echo off at top to get output also the command lines and entire command blocks after preprocessing before execution.
It looks like delayed environment variable expansion as needed on accessing an environment variable within a command block being modified in same command block is not completely unknown as the line Echo !_mm%! indicates although being syntactically wrong. Open a command prompt window, run set /? and read the help output into the window carefully and completely. Delayed environment variable expansion is explained by help of command SET on an IF and a FOR example on which command blocks are most often used. The help of SET explains also arithmetic expression in detail.
Here is a solution not using delayed environment variable expansion by using a different process flow and which handles correct also month values 08 and 09. See second comment block for details.
rem This integer increment is problematic in case of value is 08 or 09.
rem See the month increment below how to handle such values also correct.
set /A _dd+=3
echo %_dd%
if %_dd% LEQ 27 goto MakeTwoDigitDay
set "_dd=01"
rem 08 and 09 would be interpreted as invalid octal numbers. Therefore do a
rem string concatenation with 1 if the first character is a leading zero for
rem month to change month value from 01-09 to 101-109 to get the month value
rem with a leading 0 interpreted as decimal number and add 1. Otherwise add
rem 101 to months 1-12 with no leading 0. Then assign to month variable
rem just the last two digits of the month value being greater than 100.
if "%_mm:~0,1%" == "0" ( set /A "_mm=1%_mm% + 1" ) else ( set /A "_mm+=101" )
set "_mm=%_mm:~-2%"
echo %_mm%
:MakeTwoDigitDay
if "%_dd:~1%" == "" set "_dd=0%_dd%"
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
goto /?
if /?
rem /?
set /?
Few issues here. You are trying to use delayed expansion without setlocal enableDelayedExpansion clause. With the given test data you'll never enter the last IF. You are setting value inside brackets block without proper usage of delayed variable expansion.It's better to have setlocal/endlocal blocks. CHeck this:
#echo off
:: to use variable expansion with ! you need delayed expansion
setlocal enableDelayedExpansion
Set /A _dd=%_dd%+3
REM **Set /A _mm=%_mm%+1**
echo %_dd%
IF %_dd% LSS 10 Set _dd=0%_dd%
echo %_dd%
::set another value to _dd to match the last if condition
set /a _dd=30
::::
IF %_dd% GTR 27 (
Set _dd=01
Set /A _mm=_mm+1
Set _mm=0!_mm!
Echo !_mm%!
)
endlocal
The problem, (as it appears you have almost realised), is that variable expansion requires delaying in the If block.
Set /A _dd +=3
:: Set /A _mm +=1
Echo %_dd%
If %_dd% Lss 10 Set "_dd=0%_dd%"
IF %_dd% Gtr 27 (
Set "_dd=01"
Set /A _mm +=1
Set "_mm=0!_mm!"
Echo !_mm! )
Prior to using delayed expansion, you need to ensure that it has been enabled using:
SetLocal EnableDelayedExpansion
I have some problems with batch file. The file should accept input of 2 numbers from user and then accept input of sign. After that compare users entered sign with "+" sign, however it's not working.
Maybe you will be able to understand better from my code:
echo please enter first number
set /p number0=
echo please enter second number
set /p number1=
echo enter one of the numbers - ^+ - / ^*
set /p symbol="set the variable: "
echo %symbol%
set plus=+
echo %plus%
pause
if /i "%symbol%" EQU "+"(
echo your choice is to sum up the numbers
pause
set /a answ = %number0% + %number1%
echo answer:
echo %answ%
)
I already tried using if /i %symbol% == plus, tried to use quotes in any combination I was able to imagine. I tried to assign operator plus variable like this set /p plus="+" then using "" around symbol variable, and so on.
But still nothing works, after I reach part where variable should be compared with symbol + my batch file just crashes. All variables are assigned correctly.
That's the link to see full file if it's necessary, however please note that full file isn't written in English language: https://1drv.ms/u/s!Ap4-t2P-Igzihb5shQZLNkKySEWOrQ.
I have found a way to do same thing without if statement. It turns out I can just do this:
set /p number1=
set /p number2=
set /p symbol=
set /a answ=%number1%%symbol%%number2%
I suggest this code:
#echo off
setlocal EnableExtensions EnableDelayedExpansion
set Number1=
set /P "Number1=First number: "
set Number2=
set /P "Number2=Second number: "
:EnterOperator
set Operator=
set /P "Operator=Math. operator: "
if not defined Operator goto EnterOperator
if "!Operator!" == "+" goto EvaluateExpression
if "!Operator!" == "-" goto EvaluateExpression
if "!Operator!" == "*" goto EvaluateExpression
if "!Operator!" == "/" goto EvaluateExpression
goto EnterOperator
:EvaluateExpression
set /A Result=Number1 %Operator% Number2
echo The result is: %Result%
endlocal
Read the help output on running a command prompt window set /? carefully regarding to arithmetic expressions. On using just the environment variable names Number1 and Number2 as it is possible in an arithmetic expression, the string entered by the user can be also nothing or not an integer number in which case Windows command interpreter replaces the not existing environment variable or the invalid string by value 0 on evaluation of the arithmetic expression.
The arithmetic symbol respectively operator must be evaluated using delayed environment variable expansion before evaluating the arithmetic expression as otherwise Windows command interpreter could output an error message because of an invalid operator or something completely different is done depending on what the user inputs on prompt for the operator.
Please note that a division by zero is still possible by this code.
See answer on Use IF statement on variables with unacceptable symbols (e.g. / or :) for the reason using delayed environment variable expression on comparing the operator strings before using in arithmetic expression with expansion before executing this command line. See also Why is no string output with 'echo %var%' after using 'set var = text' on command line? with general information about SET syntax.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
goto /?
if /?
set /?
setlocal /?
I know the question is a little confusing.
This is my script. (easy version)
I've set up those variables
p1 = 1
p2 = 0
p3 = 1
and it goes on and on.
I want to show a list of all of those P values. Then,
I setup a variable "i"
set /a i = 0
:loop
set /a i = %i% + 1
echo P%i% = %p%i%%
goto loop
but then I realized that %p%i%% is not working...
It won't go to %p1% and show me "1",
it just shows me %p1%. and in my full script, it shows me something crazy... SO CAN ANYONE HELP ME OUT HERE?? THANKS A LOT!!
Two simple ways.
The first is to use delayed expansion.
First expand i with %i% and later the expression !p1!
Or use CALL to parse a line a second time.
The line call echo P%i% = %%p%i%%% after the first parse looks like
call echo P1 = %p1%
The second parse will expand %p1% to the content.
setlocal EnableDelayedExpansion
set p1=1
set p2=0
set p3=1
set /a i = 0
:loop
set /a i = %i% + 1
echo P%i% = !p%i%!
call echo P%i% = %%p%i%%%
if %i% == 3 exit /b
goto loop
Or another solution using a for loop
for /L %%i in (1 1 3) do (
echo P%%i = !p%%i!
)
I offer two more solutions in addition to the solutions in answer of jeb not using delayed expansion:
#echo off
setlocal EnableExtensions DisableDelayedExpansion
set "MyP1=1"
set "MyP2=0"
set "MyP3=5"
set "Count=0"
for /F "tokens=1* delims==" %%I in ('set MyP 2^>nul') do echo Variable %%I has value %%J & set /A Count+=1
echo Variables count is: %Count%
echo/
set "Index=1"
:Loop
if not defined MyP%Index% goto ExitLoop
set /A Value=MyP%Index%
echo Variable MyP%Index% has value %Value%
set /A Index+=1
goto Loop
:ExitLoop
set /A Index-=1
echo Variables count is: %Count%
endlocal
echo/
pause
The environment variables with undetermined number start all with the string MyP. The first approach runs set MyP in a separate command process in background which outputs all environment variables starting with MyP with their values sorted alphabetically, i.e. the output is for this batch code:
MyP1=1
MyP2=0
MyP3=5
This output is processed line by line by FOR which splits each line up into two substrings because of delims== with first substring being name of the environment variable assigned to loop variable I and everything after first equal sign in the line assigned to next loop variable J according to ASCII table which is the value of the environment variable because of tokens=1*.
The names of the environment variables and their values are output with counting the number of variables starting with MyP which is also output after the FOR loop.
The number of the environment variables must not be consecutive increasing for the first solution.
The second solution uses a loop without FOR. This loop requires that the environment variables have an incrementing number in their names. The loop exits if there is no more environment variable with current index number in name.
The value of the current environment variable is assigned to environment variable Value using an arithmetic expression because in this case a string like MyP1 in the arithmetic expression is interpreted as name of an environment variable whose value should be converted to an integer for evaluation of the expression. The integer result of the arithmetic expression is converted back to a string and assigned to the environment variable left to the equal sign.
The answer on Why is no string output with 'echo %var%' after using 'set var = text' on command line? might be helpful to understand the environment variables usage techniques as used here.
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
endlocal /?
for /?
goto /?
if /?
pause /?
setlocal /?
See also Single line with multiple commands using Windows batch file for an explanation of & operator used on FOR command line to avoid the need of a command block.