При вводе первого числа, символа и второго числа. Терминал линукса выдает ошибку такой команды не найдено. Программа калькулятор

Рейтинг: 0Ответов: 1Опубликовано: 15.04.2023

Например 1000 - 7 должен выдавать результат 1000 - 7 = 993

На с++ я также написал калькулятор но там все работает, а здесь нет

Вот

Calc<< 1000 - 7
user:~/MyCode$ 000 - 7
000: команда не найдена
user:~/MyCode$ 

код

package main

import (
    "fmt"
)

func main() {
    
    var con, conq int

    var numi1, numi2 int
    var numf1, numf2 float64
    var sym string

    fmt.Print("\n\n Hello user_name\n")
    fmt.Print("Calc> Enter (1) for choose base calc or (2) pro calc. *exit(66)\nCalc<< ")
    fmt.Scanf("%d", &con)

    if(con == 1){
        fmt.Print("Calc> Enter please number for choose module, Helper(1), CalcInt(2), CalcFloatPoint(3)\nCalc<< ")
        fmt.Scanf("%d", &conq)

        if conq == 1{
            fmt.Print("Calc> Enter number for choose module help\nCalc<< ")
            fmt.Scanf("%s", &sym)
            fhelper(sym)
        }

        if conq == 2{
            fmt.Print("Calc> Enter first number, symbol(+,-,*,%,/) and yet number\nCalc<< ")
            fmt.Scanf("%d", "%s", numi1, numi2, sym)
        }

        if conq == 3{
            fmt.Print("Calc> Enter first number, symbol(+,-,*,%,/) and yet number\nCalc<< ")
            fmt.Scanf("%d", "%s", numf1, numf2, sym)
        }
    }
}

func fhelper(symb string){
    switch(symb){
        case "1":
            fmt.Print("\nCalc>> This module for help you\n")
        case "2":
            fmt.Print("\nCalc>> This module for Calculation with integer numbers.\nPrototype: 1 + 1 = 2 or 1000 - 7 = 993\n")
        case "3":
            fmt.Print("\nCalc>> This module for Calculation with float point numbers.\nPrototype: 1.0 + 1.0 = 2.0 or 13.5 - 0.5 = 13\n")   
    }
}

func fCalcInteger(fnum, snum int, symb string){
    var result int

    switch symb {
        case "+":
            result = fnum + snum
            fmt.Printf("Calc>>: %d + %d = %d", fnum, snum, result)
        case "-":
            result = fnum - snum
            fmt.Printf("Calc>>: %d - %d = %d", fnum, snum, result)
        case "*":
            result = fnum * snum
            fmt.Printf("Calc>>: %d * %d = %d", fnum, snum, result)
        case "%":
            result = fnum % snum
            fmt.Printf("Calc>>: %d % %d = %d", fnum, snum, result)
        case "/":
            result = fnum / snum
            fmt.Printf("Calc>>: %d / %d = %d", fnum, snum, result)
    }
}

func fCalcFloat(fnum, snum float64, symb string){
    var result float64

    switch(symb){
        case "+":
            result = fnum + snum
            fmt.Printf("Calc>>: %d + %d = %d", fnum, snum, result)
        case "-":
            result = fnum - snum
            fmt.Printf("Calc>>: %d - %d = %d", fnum, snum, result)
        case "*":
            result = fnum * snum
            fmt.Printf("Calc>>: %d * %d = %d", fnum, snum, result)
        case "/":
            result = fnum / snum
            fmt.Printf("Calc>>: %d / %d = %d", fnum, snum, result)
    }
}

Ответы

▲ 0Принят

Вот в это месте у вас Scanf валится, прочитав первый символ:

fmt.Scanf("%d", "%s", numi1, numi2, sym)

Он не может интрепретировать "%s" как объект, куда читать целое число. Поэтому завершается с ошибкой после первого же символа.

Все последующие символы, т.е. в вашем примере 000 - 7, остаются в stdin, откуда их считывает bash и пытается проинтепретировать. bash разбирает строку 000 - 7 так:

  • 000 имя команды
  • - первый аргумент
  • 7 второй аргумент

Команда 000 в системе не зарегистрирована, о чём bash вас информирует.

Я бы на вашем месте парсил либо руками, вынимая символы из stdin и строя числа из цифр самостоятельно, либо сделал бы разбор регулярным выражением:

        if conq == 2 {
            var err error
            fmt.Print("Calc> Enter first number, symbol(+,-,*,%,/) and yet number\nCalc<< ")
            // read line
            scanner := bufio.NewScanner(os.Stdin)
            scanner.Scan()
            checkError(scanner.Err())
            line := scanner.Text()
            // parse line:
            // line format is `START may-be-spaces DIGITS may-be-spaces ONE-OF(+-*/%) may-be-spaces DIGITS may-be-spaces END`
            re := regexp.MustCompile(`^\s*([0-9]+)\s*([-+*/%])\s*([0-9]+)\s*$`)
            matches := re.FindStringSubmatch(line)
            if len(matches) < 4 {
                // Doesn't match
                checkError(fmt.Errorf("wrong line format: `%s`", line))
            }
            numi1, err = strconv.Atoi(matches[1])
            checkError(err, "failed to parse: ")
            numi2, err = strconv.Atoi(matches[3])
            checkError(err, "failed to parse", matches[3])
            sym = matches[2]
            fCalcInteger(numi1, numi2, sym)
        }

Здесь checkError печатает сообщение об ошибке и завершает программу

func checkError(err error, a ...any) {
    if err != nil {
        if a == nil {
            log.Fatal(err)
        } else {
            msg, ok := a[0].(string)
            if ok {
                a = append([]any{msg, err}, a[1:]...)
            } else {
                a = append([]any{err}, a...)
            }
            log.Fatal(a...)
        }
    }
}

Обязательно проверяйте ошибки в Го!