带有嵌套循环的嵌套 if 语句

Nested if statements with nested loops

我正在尝试制作一个简单的计算器。我敢肯定,如果您只看一眼这段代码,您就会明白我正在尝试做什么。 输入一个数字,然后选择一个操作数,然后 vim 应该用你的数字和操作数打印出一个 table 最多 15...

也许这个方法很愚蠢,试图在嵌套的 if 语句中嵌套大量循环。但我是 bash.

的新手

错误是 'Unexpected token near else' 第 24 行,但我觉得我不理解嵌套的基本问题。

这是当前代码。

#!/bin/bash
choice=6
read -p "Enter a number bruv" num
#choose operand.
echo "Now choose an operand comrade"
#choices

echo "1. *"
echo "2. +"
echo "3. -"
echo "4. /"
echo "5. ^"

echo -n "Please choose [1,2,3,4,5]"

while [ $choice -eq 6 ]; do
        read choice

        if [ $choice -eq 1 ] ; then
                for((i=0;i<=15;i++))
                do
                echo -n "$i * $num = $[ $i * $num ] "
                echo " "
        else
                if [ $choice -eq 2 ] ; then
                        for((i=0;i<=15;i++))
                        do
                        echo -n "$i + $num = $[ $i + $num ] "
                        echo " "
                else
                        if [ $choice -eq 3 ] ; then
                                for((i=0;i<=15;i++))
                                do
                                echo -n "$i - $num = $[ $i - $num ] "
                                echo " "
                        else
                                if [ $choice -eq 4 ] ; then
                                        for((i=0;i<=15;i++))
                                        do
                                        echo -n "$i / $num = $[ $i / $num ] "
                                        echo " "
                                else
                                        if [ $choice -eq 5 ] ; then
                                       for((i=0;i<=15;i++))
                                        do
                                        echo -n "$i ^$num = $[ $i ^$num ] "
                                        echo " "
                                else echo "Please choose between 1 and 5!!!"
                                          echo "1. *"
                                         echo "2. +"
                                          echo "3. -"
                                          echo "4. /"
                                           echo "5. ^"
                                        echo -n "Please choose [1,2,3,4,5]"
                              fi
                     fi
             fi
        fi
     fi
done


                                                                       

实施这个会更好吗?

# !/bin/bash
  
# Take user Input
echo "Enter number : "
read a

  
# Input type of operation
echo "Enter Choice :"
echo "1. Addition"
echo "2. Subtraction"
echo "3. Multiplication"
echo "4. Division"
echo "5. Power"
read ch
  
# Switch Case to perform
# calulator operations
case $ch in
  1)res=`for((i=0;i<=15;i++))
                                do
                                echo -n "$i - $num = $[ $i - $num ] "
                                echo " "`
  ;;
  2)res=`for((i=0;i<=15;i++))
                                do
                                echo -n "$i - $num = $[ $i - $num ] "
                                echo " "`
  ;;
  3)res=`for((i=0;i<=15;i++))
                                do
                                echo -n "$i - $num = $[ $i - $num ] "
                                echo " "`
  ;;
  4)res=`for((i=0;i<=15;i++))
                                do
                                echo -n "$i - $num = $[ $i - $num ] "
                                echo " "c`
  ;;
esac
echo "Result : $res" ```

这是一个解决方案,使用一个函数:

#! /bin/bash

ITER_MAX=15

show_values() # n op
{
    local n= op=
    for ((i=0; i<=ITER_MAX; i++)); do
        ((i>0)) && echo -n " ; "
        echo -n "$i $op $n = $((i $op n))"
    done
    echo
}

# Take user Input
read -p "Enter number : " a

# Input type of operation
echo "Enter Choice (Ctrl+C to stop):"
PS3=">> "
select ch in Addition Subtraction Multiplication Division Power ; do
  case "$ch" in
    Add*) op="+" ;;
    Sub*) op="-" ;;
    Mul*) op="*" ;;
    Div*) op="/" ;;
    Pow*) op="**" ;;
    *) echo "Bad choice, abort" >&2 ; break ;;
  esac
  show_values "$a" "$op"
done

一些解释:

  • (( ))是算术求值,$(( ))是算术展开
  • ((i>0)) && echo -n " ; " 等同于 if ((i>0)); then echo -n " ; " ; fi
  • read -p "Enter number : " a 等同于 echo -n "Enter number : " ; read a
  • 关于 select,请在您的 bash 终端中查看 help select

使用https://www.shellcheck.net/

 
Line 20:
                for((i=0;i<=15;i++))
                ^-- SC1009: The mentioned syntax error was in this for loop.
                   ^-- SC1073: Couldn't parse this arithmetic for condition. Fix to allow more checks.
 
Line 21:
                do
                ^-- SC1061: Couldn't find 'done' for this 'do'.
 
Line 24:
        else
        ^-- SC1062: Expected 'done' matching previously mentioned 'do'.
            ^-- SC1072: Unexpected keyword/token. Fix any mentioned problems and try again.

另一个选择:

read -p "Enter a number and an operator: " -a a
for n in {1..15}; do printf "%+10s\n" $((${a[@]} $n)); done

-p 告诉 read 提供提示。 -a 读入数组(此处命名为 a)。
{1..15} 是内置的 bash 序列语法。
%+10s 告诉 printf space-pad/right 证明 10 个字符。
${a[@]} 替换为数组的所有元素 - 数字,然后是运算符。
$(( ... )) 进行算术处理并用结果(作为字符串)替换自身。

因此,如果您输入“10 *”,那么 $((${a[@]} $n)) 会第一次处理 10 * 1,因此 printf "%+10s\n" $((${a[@]} $n)) 会输出带有尾随换行符的“10”。然后循环在每次迭代中将 1 替换为下一个数字,最多 15。这也允许其他运算符,例如 % 用于模数,但如果给出无效内容将崩溃。

如果要错误检查 -

while [[ ! "${a[*]}" =~ ^[0-9][0-9]*\ ([*/+-]|\*\*)$ ]]
do read -p "Enter a, integer and an operator (one of: + - * / **) " -a a
done
for n in {1..15}; do printf "%+10s\n" $((${a[@]} $n)); done

如果你想要浮点数学,试试bc:

while [[ ! "${a[*]}" =~ ^[0-9]+.?[0-9]*\ ([*/+-]|\*\*)$ ]]
do read -p "Enter a, integer and an operator (one of: + - * / **) " -a a
done
for n in {1..15}; do printf "%+15s\n" $(bc -l  <<< "scale=3;${a[@]} $n"); done

个人,我会将输入放在命令行上。不那么模糊,尽管它可能需要引用 * 运算符,具体取决于您 运行 它的方式和目录中的内容。

#!/bin/bash

me=${0##*/}
use="
  use: $me {number} {operator} [iterations] [scale]

  Numbers may include one decimal point.
  Operators must be one of: + - * / **

"
while getopts "n:o:i:s:" arg
do case $arg in
   n) n="$OPTARG" ;;
   o) o="$OPTARG" ;;
   i) i="$OPTARG" ;;
   s) s="$OPTARG" ;;
   *) printf "%s\n" "Invalid argument '$arg' $use";
      exit 1;;
   esac
done

[[ -n "$n" && -n "$o"             ]] || { echo                                                     "$use"; exit 1; }
[[ "$n"       =~ ^[0-9]+.?[0-9]*$ ]] || { printf "%s\n" "Invalid number   '$n'                      $use"; exit 1; }
[[ "$o"       =~ ^([*/^+-]|\*\*)$ ]] || { printf "%s\n" "Invalid operator '$o'                      $use"; exit 1; }
[[ "${i:=15}" =~ ^[0-9]+.?[0-9.]$ ]] || { printf "%s\n" "Invalid number   '$i'                      $use"; exit 1; }
[[ "${s:=3}"  =~ ^[0-9]+$         ]] || { printf "%s\n" "Invalid scale    '$s' (must be an integer) $use"; exit 1; }

c=1
while ((c < i))
do printf "%+15s\n" $(bc -l <<< "scale=$s; $n $o $c")
   ((c++))
done