批处理文件 "Unbalanced Parenthesis"
Batch File "Unbalanced Parenthesis"
所以我正在尝试制作这个程序:
//@echo off
@title Calculate Caloric Needs
set /p name=What is the name of the individual in question?
CLS
:START
set /p sex=Is %name% a M(ale) or F(emale)? (M/F)
CLS
if NOT %sex%==M if NOT %sex%==F (
echo Invalid Selection...Try Again....
goto START
)
set /p w=What is the target weight of %name%?
CLS
set /p h=What is the height of %name% IN INCHES?
CLS
set /p a=What is the age of %name%?
CLS
if %sex%==M set /a result=66 + (6.23 * %w%) + (12.7 * %h%) - (6.8 * %a%)
if %sex%==F set /a result=655+(4.35*%w%)+(4.7*%h%)-(4.7*%a%)
echo %result% is the caloric intake for %name%.
pause
exit
为了进行故障排除,@echo off
已被禁用。
这是一个简单的程序,用于计算一些热量摄入量,这些计算逐项计算起来有点困难。
每次我达到需要进行算术计算的程度时,都会发生以下两种情况之一:
- 如果我将
set /a
语句包装在 if %sex%==M ( CODE HERE )
块中,程序将意外退出而不显示错误消息。
- 如果我不这样做并且将所有内容都放在一行中(如上面发布的示例代码中所示),那么我会收到消息
Unbalanced Parenthesis
而无需任何进一步解释(感谢 Windows。 ..).
据我所知,从数学上讲括号是完全平衡的。
我试过:
- 在
""
和 []
、set /a "result=66 + (6.23 * %w%) + (12.7 * %h%) - (6.8 * %a%)"
或 set /a [result=66 + (6.23 * %w%) + (12.7 * %h%) - (6.8 * %a%)]
中包装 set /a
语句
- 转义算术中使用的部分或全部括号
set /a result=66 + ^(6.23 * %w%^) + ^(12.7 * %h%^) - ^(6.8 * %a%^)
- 为了测试减少括号的数量
set /a result=66 + (6.23 * %w%)
。 如果我准确地使用 set /a result=66 + (6.23 * %w%)
,我实际上可以将语句包装在一个 if ( CODE HERE )
块中,并使其实际上 return 成为一个错误值。虽然报错还是Unbalanced Parenthesis
...
- 加长或缩短算术本身的空格数
set /a result=66+(6.23*%w%)+(12.7*%h%)-(6.8*%a%)
VS。 set /a result=66 + (6.23 * %w%) + (12.7 * %h%) - (6.8 * %a%)
- 以上的所有组合
所以我不知道是什么导致了这种奇怪的行为。
您收到的错误消息在您的情况下非常混乱,因为 set /A
命令行中的括号是平衡的,并且在整个命令行未放在括号内的情况下以这种方式工作代码本身。无论如何,将整个 set /A
表达式放在引号之间总是一个好主意,这样圆括号或其他特殊字符都不会造成麻烦。
方括号对 set /A
.
没有任何特殊意义
无论如何,错误的根本原因是您使用的是小数,尽管set /A
仅支持 32 位空间中的有符号整数运算(请参阅 set /?
的帮助)。在命令提示符 window 中键入 set /A (1.2*3)
,您将收到相同的错误消息;但删除 .
一切都会好起来的。
一种可能的解决方法是使用定点运算之类的东西,因此在计算过程中将所有内容乘以 10 的整数次方,最后将结果除以 10 的相同次方,或者换句话说,移动在进行计算之前将小数点移到右边,然后再将其移回。
这就是它的样子(我还修复了您代码中的一些其他问题,但请参阅下文):
@echo off
@title Calculate Caloric Needs
cls
set "name=them"
set /P "name=What is the name of the individual in question? "
:START
set "sex="
set /P "sex=Is %name% a M(ale) or F(emale)? (M/F) "
if /I not "%sex%"=="M" if /I not "%sex%"=="F" (
echo Invalid Selection... Try Again...
goto :START
)
set "w=0"
set /P "w=What is the target weight of %name%? "
set "h=0"
set /P "h=What is the height of %name% IN INCHES? "
set "h=%h%." & rem // append a decimal dot to entry in `h`
set "mil=1%h:*.=%" & rem // store everything behind first dot in `mil`, prepend `1`
set /A "h+=0, mil+=0" & rem // convert `h` to integer, dismiss fractional part
set "mil=%mil%000" & rem // pad trailing zeros to `mil`
set "mil=%mil:~,4%" & rem // extract first four numerals from `mil`
set /A "mil+=5" & rem // add `5` to `mil` for rounding
if %mil:~,1% GTR 1 set /A "h+=1" & rem // regard carry of previous addition in `h`
set "h=%h%%mil:~-3,-1%" & rem /* append second and third numeral of `mil` to `h`,
rem hence dismissing previously prepended `1`;
rem so `h` holds the height in 100ths of inches now */
set "a=0"
set /P "a=What is the age of %name%? "
rem // quotation marks avoid trouble with parenthesis or other characters;
rem /* all original constants are multiplied by `1000` to avoid fractional parts,
rem except the factor at `h` which is multiplied by `10` only due to above
rem implicit multiplication of `h` by 100, then `500` is added for rounding,
rem and finally, the result is divided by `1000` to remove the previous factors: */
if /I "%sex%"=="M" (
set /A "result=(66000+(6230*%w%)+(127*%h%)-(6800*%a%)+500)/1000"
) else if /I "%sex%"=="F" (
set /A "result=(655000+(4350*%w%)+(47*%h%)-(4700*%a%)+500)/1000"
)
echo %result% is the caloric intake for %name%.
pause
exit /B
这是我修复的:
set
和 set /P
语法得到改进,整个表达式都在引号之间,因此您避免了特殊字符的麻烦,并且您可以清楚地看到是否有尾随空格;
- 任何提示值都会被初始化,以避免在用户刚刚按下 RETURN;
时采用之前的值
- 性别条目的
if
查询已更正,现在通过添加开关 /I
不区分大小写,并且在测试变量为空的情况下不会造成问题引号内的比较表达式;
顺便说一下,您可能对此类单键输入的 choice
命令感兴趣,因为它甚至不接受任何其他字符;
- 由于上述定点算法,以英寸为单位的身高条目
h
的值被转换为英寸的百分之一(但体重 w
和年龄 a
仍然被处理作为整数);这是它的工作原理:
set "h=%h%."
:在h
中的条目后加一个点,以确保至少有一个;
set "mil=1%h:*.=%"
:将 h
中第一个点之后的所有内容存储到 mil
(小数部分),并在结果前添加 1
以不丢失任何前导零(这对小数部分很重要)一旦转换为数字;
set /A "h+=0, mil+=0"
:将h
和mil
都转换为数值(整数);这会将第一个非数字数字之前的所有内容转换为数字,忽略前导空格但关于符号 +
/-
(尽管它们无关紧要,因为此处不需要);
set "mil=%mil%000"
:在小数部分后追加 3 个零(前面的 1
仍然存在,因此始终至少有 4 个数字);
set "mil=%mil:~,4%"
:提取前4个字符(所以前缀1
再加3个数字);
set /A "mil+=5"
:添加5
,所以如果最后一个数字是5
或更多,就会出现进位,因此会发生倒数第二个数字的舍入;
if %mil:~,1% GTR 1 set /A "h+=1"
:在h
中增加整数部分以防进位超过小数部分;
set "h=%h%%mil:~-3,-1%"
:将h
的整数部分和mil
中小数部分倒数第二个数字的范围拼接起来存入h
;
result
的公式中的所有常数都乘以1000
使小数点消失,除了h
乘以10
的因数只是,因为h
已经是原高度值的100倍;之后结果除以 1000
; 500
的添加仅意味着在除以 1000
时添加 0.5
并且打算在它们之前将 .5
到 .9*
的小数部分四舍五入因整数除法而迷路;
exit
命令被 exit /B
替换以终止批处理文件,但不终止拥有的 cmd
实例;
请注意,像 //
和 /*
、*/
这样的注释在批处理文件中没有特殊含义。 rem
语句给出评论或评论。我在这里使用 rem
中的斜线式注释只是为了在本网站上突出显示一些很酷的语法...
更新
按照,结果本身应该是小数,所以我稍微修改了脚本(下面有描述):
@echo off
@title Calculate Caloric Needs
cls
set "name=them"
set /P "name=What is the name of the individual in question? "
set "male="
choice /C MF /M "Is %name% a M(ale) of F(emale)? "
if not ErrorLevel 2 set "male=Flag"
set "w=0"
set /P "w=What is the target weight of %name% IN POUNDS? "
set "h=0"
set /P "h=What is the height of %name% IN INCHES? "
set "h=%h%." & rem // append a decimal dot to entry in `h`
set "mil=1%h:*.=%" & rem // store everything behind first dot in `mil`, prepend `1`
set /A "h+=0, mil+=0" & rem // convert `h` to integer, dismiss fractional part
set "mil=%mil%000" & rem // pad trailing zeros to `mil`
set "mil=%mil:~,4%" & rem // extract first four numerals from `mil`
set /A "mil+=5" & rem // add `5` to `mil` for rounding
if %mil:~,1% GTR 1 set /A "h+=1" & rem // regard carry of previous addition in `h`
set "h=%h%%mil:~-3,-1%" & rem /* append second and third numeral of `mil` to `h`,
rem hence dismissing previously prepended `1`;
rem so `h` holds the height in 100ths of inches now */
set "a=0"
set /P "a=What is the age of %name% IN YEARS? "
rem // quotation marks avoid trouble with parenthesis or other characters;
rem /* all original constants are multiplied by `1000` to avoid fractional parts,
rem except the factor at `h` which is multiplied by `10` only due to above
rem implicit multiplication of `h` by 100, then `500` is added for rounding,
rem and finally, the result is divided by `1000` to remove the previous factors: */
if defined male (
set /A "result=66000+(6230*%w%)+(127*%h%)-(6800*%a%)+5"
) else (
set /A "result=655000+(4350*%w%)+(47*%h%)-(4700*%a%)+5"
)
echo %result:~,-3%.%result:~-3,-1% is the caloric intake for %name%.
pause
exit /B
这是我所做的:
- 基本的计算公式还是一样的,只是这次省略了除以
1000
,并且在结果中加入了5
进行四舍五入,而不是500
];但是为了显示结果,最后一个数字被忽略,并且在剩余的最后两个数字之前插入一个小数点 .
,因此结果有两个小数位;
- 性别条目现在由
choice
命令完成,如本答案原始版本中所建议的(见上文),因此不再需要简单地捕获无效结果 choice
只接受预定义的键或字符;
根据@aschipfl 的回复,这是因为我试图将 /a 与浮点数一起使用。
我使用 bc for Windows 解决了这个问题。因为现在的命令行应该默认支持像浮点运算这样基本的东西。
那是什么:
if %sex%==M set /a result=66 + (6.23 * %w%) + (12.7 * %h%) - (6.8 * %a%)
现在是:
set bc=bc\bc.exe
if /I "%sex%"=="M" echo 66 + (6.23 * %w%) + (12.7 * %h%) - (6.8 * %a%) | %bc% & echo is the caloric intake required per-day for %name%
所以我正在尝试制作这个程序:
//@echo off
@title Calculate Caloric Needs
set /p name=What is the name of the individual in question?
CLS
:START
set /p sex=Is %name% a M(ale) or F(emale)? (M/F)
CLS
if NOT %sex%==M if NOT %sex%==F (
echo Invalid Selection...Try Again....
goto START
)
set /p w=What is the target weight of %name%?
CLS
set /p h=What is the height of %name% IN INCHES?
CLS
set /p a=What is the age of %name%?
CLS
if %sex%==M set /a result=66 + (6.23 * %w%) + (12.7 * %h%) - (6.8 * %a%)
if %sex%==F set /a result=655+(4.35*%w%)+(4.7*%h%)-(4.7*%a%)
echo %result% is the caloric intake for %name%.
pause
exit
为了进行故障排除,@echo off
已被禁用。
这是一个简单的程序,用于计算一些热量摄入量,这些计算逐项计算起来有点困难。
每次我达到需要进行算术计算的程度时,都会发生以下两种情况之一:
- 如果我将
set /a
语句包装在if %sex%==M ( CODE HERE )
块中,程序将意外退出而不显示错误消息。 - 如果我不这样做并且将所有内容都放在一行中(如上面发布的示例代码中所示),那么我会收到消息
Unbalanced Parenthesis
而无需任何进一步解释(感谢 Windows。 ..).
据我所知,从数学上讲括号是完全平衡的。
我试过:
- 在
""
和[]
、set /a "result=66 + (6.23 * %w%) + (12.7 * %h%) - (6.8 * %a%)"
或set /a [result=66 + (6.23 * %w%) + (12.7 * %h%) - (6.8 * %a%)]
中包装 - 转义算术中使用的部分或全部括号
set /a result=66 + ^(6.23 * %w%^) + ^(12.7 * %h%^) - ^(6.8 * %a%^)
- 为了测试减少括号的数量
set /a result=66 + (6.23 * %w%)
。 如果我准确地使用set /a result=66 + (6.23 * %w%)
,我实际上可以将语句包装在一个if ( CODE HERE )
块中,并使其实际上 return 成为一个错误值。虽然报错还是Unbalanced Parenthesis
... - 加长或缩短算术本身的空格数
set /a result=66+(6.23*%w%)+(12.7*%h%)-(6.8*%a%)
VS。set /a result=66 + (6.23 * %w%) + (12.7 * %h%) - (6.8 * %a%)
- 以上的所有组合
set /a
语句
所以我不知道是什么导致了这种奇怪的行为。
您收到的错误消息在您的情况下非常混乱,因为 set /A
命令行中的括号是平衡的,并且在整个命令行未放在括号内的情况下以这种方式工作代码本身。无论如何,将整个 set /A
表达式放在引号之间总是一个好主意,这样圆括号或其他特殊字符都不会造成麻烦。
方括号对 set /A
.
无论如何,错误的根本原因是您使用的是小数,尽管set /A
仅支持 32 位空间中的有符号整数运算(请参阅 set /?
的帮助)。在命令提示符 window 中键入 set /A (1.2*3)
,您将收到相同的错误消息;但删除 .
一切都会好起来的。
一种可能的解决方法是使用定点运算之类的东西,因此在计算过程中将所有内容乘以 10 的整数次方,最后将结果除以 10 的相同次方,或者换句话说,移动在进行计算之前将小数点移到右边,然后再将其移回。
这就是它的样子(我还修复了您代码中的一些其他问题,但请参阅下文):
@echo off
@title Calculate Caloric Needs
cls
set "name=them"
set /P "name=What is the name of the individual in question? "
:START
set "sex="
set /P "sex=Is %name% a M(ale) or F(emale)? (M/F) "
if /I not "%sex%"=="M" if /I not "%sex%"=="F" (
echo Invalid Selection... Try Again...
goto :START
)
set "w=0"
set /P "w=What is the target weight of %name%? "
set "h=0"
set /P "h=What is the height of %name% IN INCHES? "
set "h=%h%." & rem // append a decimal dot to entry in `h`
set "mil=1%h:*.=%" & rem // store everything behind first dot in `mil`, prepend `1`
set /A "h+=0, mil+=0" & rem // convert `h` to integer, dismiss fractional part
set "mil=%mil%000" & rem // pad trailing zeros to `mil`
set "mil=%mil:~,4%" & rem // extract first four numerals from `mil`
set /A "mil+=5" & rem // add `5` to `mil` for rounding
if %mil:~,1% GTR 1 set /A "h+=1" & rem // regard carry of previous addition in `h`
set "h=%h%%mil:~-3,-1%" & rem /* append second and third numeral of `mil` to `h`,
rem hence dismissing previously prepended `1`;
rem so `h` holds the height in 100ths of inches now */
set "a=0"
set /P "a=What is the age of %name%? "
rem // quotation marks avoid trouble with parenthesis or other characters;
rem /* all original constants are multiplied by `1000` to avoid fractional parts,
rem except the factor at `h` which is multiplied by `10` only due to above
rem implicit multiplication of `h` by 100, then `500` is added for rounding,
rem and finally, the result is divided by `1000` to remove the previous factors: */
if /I "%sex%"=="M" (
set /A "result=(66000+(6230*%w%)+(127*%h%)-(6800*%a%)+500)/1000"
) else if /I "%sex%"=="F" (
set /A "result=(655000+(4350*%w%)+(47*%h%)-(4700*%a%)+500)/1000"
)
echo %result% is the caloric intake for %name%.
pause
exit /B
这是我修复的:
set
和set /P
语法得到改进,整个表达式都在引号之间,因此您避免了特殊字符的麻烦,并且您可以清楚地看到是否有尾随空格;- 任何提示值都会被初始化,以避免在用户刚刚按下 RETURN; 时采用之前的值
- 性别条目的
if
查询已更正,现在通过添加开关/I
不区分大小写,并且在测试变量为空的情况下不会造成问题引号内的比较表达式;
顺便说一下,您可能对此类单键输入的choice
命令感兴趣,因为它甚至不接受任何其他字符; - 由于上述定点算法,以英寸为单位的身高条目
h
的值被转换为英寸的百分之一(但体重w
和年龄a
仍然被处理作为整数);这是它的工作原理:set "h=%h%."
:在h
中的条目后加一个点,以确保至少有一个;set "mil=1%h:*.=%"
:将h
中第一个点之后的所有内容存储到mil
(小数部分),并在结果前添加1
以不丢失任何前导零(这对小数部分很重要)一旦转换为数字;set /A "h+=0, mil+=0"
:将h
和mil
都转换为数值(整数);这会将第一个非数字数字之前的所有内容转换为数字,忽略前导空格但关于符号+
/-
(尽管它们无关紧要,因为此处不需要);set "mil=%mil%000"
:在小数部分后追加 3 个零(前面的1
仍然存在,因此始终至少有 4 个数字);set "mil=%mil:~,4%"
:提取前4个字符(所以前缀1
再加3个数字);set /A "mil+=5"
:添加5
,所以如果最后一个数字是5
或更多,就会出现进位,因此会发生倒数第二个数字的舍入;if %mil:~,1% GTR 1 set /A "h+=1"
:在h
中增加整数部分以防进位超过小数部分;set "h=%h%%mil:~-3,-1%"
:将h
的整数部分和mil
中小数部分倒数第二个数字的范围拼接起来存入h
;
result
的公式中的所有常数都乘以1000
使小数点消失,除了h
乘以10
的因数只是,因为h
已经是原高度值的100倍;之后结果除以1000
;500
的添加仅意味着在除以1000
时添加0.5
并且打算在它们之前将.5
到.9*
的小数部分四舍五入因整数除法而迷路;exit
命令被exit /B
替换以终止批处理文件,但不终止拥有的cmd
实例;
请注意,像 //
和 /*
、*/
这样的注释在批处理文件中没有特殊含义。 rem
语句给出评论或评论。我在这里使用 rem
中的斜线式注释只是为了在本网站上突出显示一些很酷的语法...
更新
按照
@echo off
@title Calculate Caloric Needs
cls
set "name=them"
set /P "name=What is the name of the individual in question? "
set "male="
choice /C MF /M "Is %name% a M(ale) of F(emale)? "
if not ErrorLevel 2 set "male=Flag"
set "w=0"
set /P "w=What is the target weight of %name% IN POUNDS? "
set "h=0"
set /P "h=What is the height of %name% IN INCHES? "
set "h=%h%." & rem // append a decimal dot to entry in `h`
set "mil=1%h:*.=%" & rem // store everything behind first dot in `mil`, prepend `1`
set /A "h+=0, mil+=0" & rem // convert `h` to integer, dismiss fractional part
set "mil=%mil%000" & rem // pad trailing zeros to `mil`
set "mil=%mil:~,4%" & rem // extract first four numerals from `mil`
set /A "mil+=5" & rem // add `5` to `mil` for rounding
if %mil:~,1% GTR 1 set /A "h+=1" & rem // regard carry of previous addition in `h`
set "h=%h%%mil:~-3,-1%" & rem /* append second and third numeral of `mil` to `h`,
rem hence dismissing previously prepended `1`;
rem so `h` holds the height in 100ths of inches now */
set "a=0"
set /P "a=What is the age of %name% IN YEARS? "
rem // quotation marks avoid trouble with parenthesis or other characters;
rem /* all original constants are multiplied by `1000` to avoid fractional parts,
rem except the factor at `h` which is multiplied by `10` only due to above
rem implicit multiplication of `h` by 100, then `500` is added for rounding,
rem and finally, the result is divided by `1000` to remove the previous factors: */
if defined male (
set /A "result=66000+(6230*%w%)+(127*%h%)-(6800*%a%)+5"
) else (
set /A "result=655000+(4350*%w%)+(47*%h%)-(4700*%a%)+5"
)
echo %result:~,-3%.%result:~-3,-1% is the caloric intake for %name%.
pause
exit /B
这是我所做的:
- 基本的计算公式还是一样的,只是这次省略了除以
1000
,并且在结果中加入了5
进行四舍五入,而不是500
];但是为了显示结果,最后一个数字被忽略,并且在剩余的最后两个数字之前插入一个小数点.
,因此结果有两个小数位; - 性别条目现在由
choice
命令完成,如本答案原始版本中所建议的(见上文),因此不再需要简单地捕获无效结果choice
只接受预定义的键或字符;
根据@aschipfl 的回复,这是因为我试图将 /a 与浮点数一起使用。
我使用 bc for Windows 解决了这个问题。因为现在的命令行应该默认支持像浮点运算这样基本的东西。
那是什么:
if %sex%==M set /a result=66 + (6.23 * %w%) + (12.7 * %h%) - (6.8 * %a%)
现在是:
set bc=bc\bc.exe
if /I "%sex%"=="M" echo 66 + (6.23 * %w%) + (12.7 * %h%) - (6.8 * %a%) | %bc% & echo is the caloric intake required per-day for %name%