Reputation: 199
I wrote a code to calculate some expressions. It works like this:calc 5+ 6 + 8*7
must output 67.
The problem that I faced is bitwise operators:calc 1 ^& 0
gives error. Idea of my calc is simple. First stick all our input together in set a
and then set /A a=%a%
to calculate the expression
My code:
@echo off
if "%1" == "" goto :help
if "%1" == "/?" goto :help
set "g="
:start
rem ***Stick all our input together***
set "g=%g%%1"
if not "%1" == "" (
if "%1" == "/?" (
goto :help
)
shift
goto :start
)
echo %g%| findstr /R "[^0123456789\+\-\*\/\(\)] \+\+ \-\- \*\* \/\/ \= \=\= \^^" >nul 2>&1
if not ERRORLEVEL 1 goto error
set /A "g=%g%" 2>nul
if ERRORLEVEL 1 goto error
echo %g%
set g=
goto :EOF
:help
echo This is simple calculator
echo Usage: Mycalc.cmd [/?] (EXPRESSION)
echo Available operands:+,-,*,/,(,)
goto :EOF
:error
echo Wrong input or calculation error.
I think that the problem when we enter calc 1 ^& 0
there is error to echo %g%
: 0 is not recognized as an internal or external command
Upvotes: 2
Views: 3077
Reputation: 11367
DelayedExpansion
or goto
statements.@echo off
setlocal DisableDelayedExpansion
set "Input=%*"
rem No Input, display help
if not defined Input ( call :Help ) else call :Main || call :Error
endlocal & exit /b %ErrorLevel%
:Main
rem Clean Input of poison double quotations
set "Input=%Input:"=%"
rem Check for the /? help parameter
if "/?"=="%Input:~0,2%" call :Help & exit /b 0
rem Validate the characters in the Input
for /f "delims=0123456789+-*/()&| " %%A in ("%Input%") do exit /b 1
rem Perform the calculations
set /a "Input=%Input: =%" 2>nul
rem Validate the Result
for /f "delims=0123456789" %%A in ("%Input%") do exit /b 1
rem Display the Result
echo(%Input%
exit /b %ErrorLevel%
:Help
echo This is simple calculator
echo Usage: Mycalc.cmd [/?] (EXPRESSION)
echo Available operands:+,-,*,/,^(,^),^&,^|
exit /b 0
:Error
echo Wrong input or calculation error.
exit /b 0
Upvotes: 0
Reputation: 20464
Your original code needed some fixes and code simplifications, here is a working version:
@echo off
if "%~1" EQU "" (goto :help)
if "%~1" EQU "/?" (goto :help)
:start
rem ***Stick all our input together***
Set "g=%*"
set /A "g=%g: =%"
REM echo Input: "%g%"
set /A "g=%g%" 2>nul || (goto error)
echo %g%
set "g="
goto :EOF
:help
echo This is simple calculator
echo Usage: Mycalc.cmd [/?] (EXPRESSION)
echo Available operands:+,-,*,/,(,)
goto :EOF
:error
echo Wrong input or calculation error.
PS: Try it as normally without passing additional (I mean double or triple) ^
characters.
Upvotes: 1
Reputation: 82327
The problem is the output of &
or |
as MC ND and aphoria mentioned.
To solve it use at best delayed expansion, as this doesn't care about these characters.
This can handle calc 1^&3
or also calc "1&3"
setlocal EnableDelayedExpansion
set "param=%~1"
echo !param!
But you got extra problems as you try to pipe this to findstr, this needs extra handling
Upvotes: 2
Reputation: 70933
The problem is the & character. You can force the command line to accept & as a valid character as you are doing it, with ^ prefix, but once it is in a variable, each time you use this variable in the batch file you get a real ampersand.
In your example, calling calc 1 ^& 0 , when executing
echo %g%
what the cmd file is running is
echo 1 & 0
echo the character 1 and run program 0
How to solve?
rem read all command line and put inside quotes
set a="%*"
rem replace ampersand with escaped ampersand
set a=%a:&=^&%
rem execute calculation without quotes
set /a a=%a:"=%
And, of course, call cmd with escaped ampersand
Upvotes: 2