0

Just starting with rust and trying to build a simple calculator that takes in a number, then an operator, and then another number. I have this function that is supposed to return answer to the equation.

fn equation(num1: i64, op: String, num2: i64) -> i64{
    if op.eq("+"){
        num1+num2
    } else if op.eq("-"){
        num1-num2
    } else if op.eq("*"){
        num1*num2
    } else if op.eq("/"){
        num1/num2
    } else{
        0
    }
}

The problem is, it returns 0 every time. However, if instead of comparing a string, I use an integer where 1 is +, 2 is -, 3 is * and 4 is /, it works fine

fn equation(num1: i64, op: i64, num2: i64) -> i64{
    if op == 1{
        num1+num2
    } else if op == 2{
        num1-num2
    } else if op == 3{
        num1*num2
    } else if op == 4{
        num1/num2
    } else{
        0
    }
}

^^ This returns the correct solution without any issues, can anyone tell me what I'm doing wrong here? Here is what my whole project looks like in case the issue lies elsewhere

use std::io;

fn main() {
    let mut num1 = String::new();
    println!("Enter your first number:");

    io::stdin()
        .read_line(&mut num1)
        .expect("Failed to enter number.");
    
    let num_1: i64 = num1.trim().parse::<i64>().unwrap();
    //let num_1: i64 = num1.trim().parse().expect("figure out whats happening here");
    println!("{num1}");


    println!("Enter your operator (+ - * /):");
    let mut op = String::new();

    io::stdin()
        .read_line(&mut op)
        .expect("failed to enter operator.");

    let mut num2 = String::new();
    println!("Enter your second number:");

    io::stdin()
        .read_line(&mut num2)
        .expect("Failed to enter numbers.");

    let num_2 = num2.trim().parse::<i64>().unwrap();

    println!("Your answer: {}", equation(num_1, op, num_2));

}
fn equation(num1: i64, op: String, num2: i64) -> i64{
    if op.eq("+"){
        num1+num2
    } else if op.eq("-"){
        num1-num2
    } else if op.eq("*"){
        num1*num2
    } else if op.eq("/"){
        num1/num2
    } else{
        0
    }
}
Jacob
  • 1

3 Answers3

1

Yes, yes, all the people here are right.

  • You should trim the op (which is the actual solution to your question)
  • Using match is much simpler than a long list of ifs
  • Usually &str is used instead of String as argument type for strings

Further:

  • You can reduce code duplication by wrapping the read_line functionality in a function/closure
  • Your .expect("Failed to enter number.") is at the wrong position, it should be at the point where you unwrap the .parse()
  • You don't need type annotations around your .parse(), they propagate all the way up from equation

With all of those things fixed:

use std::io;

fn main() {
    let stdin = io::stdin();
    let read_input = move |msg: &str| {
        println!("{}", msg);
        let mut line = String::new();
        stdin.read_line(&mut line).unwrap();
        line.trim().to_string()
    };

    let num_1 = read_input("Enter your first number:")
        .parse()
        .expect("Failed to enter number");

    let op = read_input("Enter your operator (+ - * /):");

    let num_2 = read_input("Enter your second number:")
        .parse()
        .expect("Failed to enter number");

    println!("Your answer: {}", equation(num_1, &op, num_2));
}

fn equation(num1: i64, op: &str, num2: i64) -> i64 {
    match op {
        "+" => num1 + num2,
        "-" => num1 - num2,
        "*" => num1 * num2,
        "/" => num1 / num2,
        _ => 0,
    }
}
Enter your first number:
3
Enter your operator (+ - * /):
*
Enter your second number:
5
Your answer: 15
Finomnis
  • 18,094
  • 1
  • 20
  • 27
0

Your forgot to trim the newline character in op

println!("Your answer: {}", equation(num_1, op.trim().to_string(), num_2));
$ cargo run -q
Enter your first number:
1
1

Enter your operator (+ - * /):
+
Enter your second number:
2
Your answer: 3
Steve Lau
  • 658
  • 7
  • 13
-1

It seems that the problem is that you are expecting a "String" as the second parameter in the equation function as opposed to a "&str" which is different in the Rust language. The link below is a good reference to see the difference between the two. Happy coding!

What are the differences between Rust's `String` and `str`?

will_g
  • 1
  • 1
  • I tried to incorporate &str by changing the function to take in op: &str, and the part of my code that calls upon the function to look like this: `println!("Your answer: {}", equation(num_1, &op, num_2));` but it's still not working, how can I fix this? – Jacob Jul 06 '22 at 23:59
  • we do have implementation of [PartialEq<&str> for String](https://doc.rust-lang.org/std/string/struct.String.html#impl-PartialEq%3C%26%27a%20str%3E) – Steve Lau Jul 07 '22 at 00:52