Comparing captured keyboard strings to Rust

Asked

Viewed 35 times

5

I’m trying to learn Rust and naturally I’m starting with "The Book". At the end of chapter 3 has 3 simple logic exercises, and one of them is the classic converter from Fahrenheit to Celcius.

I noticed a strange behavior to start the block if. In case I don’t put the .trim() when I call the variable fahrenheit which has just received the value from the keyboard, it does not enter the if (line 14).

What makes me a little confused is that, this simple code that I tested on the playground runs normally returning true/false:

fn main() {
    let var1 = "um";
    let var2 = "um";
    let result: bool = var1 == var2;
    
    println!("{}", result);
}

I imagine that when you take something from the keyboard, some character is inserted at the beginning or end of the line. Does anyone know anything about?

Code:

use std::io;

fn main() {
    println!("## Bem vindo ao conversor de Fahrenheit-2-Celcius! ##");

    let mut loop_control: bool = true;
    while loop_control {
        println!("Insira o valor em graus Fahrenheit ou 'quit' para sair:");
        let mut fahrenheit = String::new();
        io::stdin()
            .read_line(&mut fahrenheit)
            .expect("Deve ser um valor numérico ou 'quit' para sair.");

        if fahrenheit.trim() == "quit" {
            println!("Saindo... até a próxima!");
            loop_control = false;
        } else {
            let fahrenheit: f64 = fahrenheit.trim().parse().expect("Digite um número.");
            let celsius = (fahrenheit - 32.0) / 1.8;
            println!("{} fahrenheit é/são {} em celsius.", fahrenheit, celsius);
        }
    }
}

1 answer

5


The method read_line, that you are using to read the user input from stdin, reads the input until you find a line break - usually represented by \n.

Note in this example that the modified string will contain the break:

fn main() {
    let mut input = String::new();
    std::io::stdin().read_line(&mut input).unwrap();

    dbg!(input); // [src/main.rs:5] input = "Foo\n"
}

It is not to be expected that a comparison between "Foo" and "Foo\n" return true. To correct this, you must use the method trim, that returns a string Slice where the ends are without the space characters (line breaks, spaces, etc).

With the result of trim, you will be comparing the same strings (since you will know that the line break will not be there).


And you don’t have to call trim twice. Just create a new variable and store the value returned by the method trim.

It doesn’t have much to do with the question, but you can remove the boolean loop_control makes a move by using an infinite loop and using an break to leave when needed. See that the code is much cleaner.

  • Ahhh understood. I really imagined that there should be some character being inserted at the beginning or end of the line, but I couldn’t find it. Thank you so much for the answer! About the break was aware, it is used in cap2 when we program the guessing game. But as it will be discussed in more depth in the future of the book I decided not to use it even... Thanks again!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.