Skip to Content
Course content

13: Practice Exercise: Building a Simple Temperature Converter

Click on the "Edit" button in the top corner of the screen to edit your slide content.

How do I actually get a number from the user?

Getting input in Rust is a bit more verbose than in Python or JavaScript, and it's where most people get tripped up during their first few CLI tools. You can't just call a simple input() function. You need to bring std::io into play.

The trick is that std::io::stdin().read_line(&mut string) gives you a String, but for a temperature converter, you need a float. You'll have to trim the trailing newline character (because hitting 'Enter' adds one) and then parse it. It looks something like this:

use std::io;

let mut input = String::new();
io::stdin().read_line(&mut input).expect("Failed to read line");

// Trim the whitespace/newline and parse to f64
let temp: f64 = input.trim().parse().expect("Please type a valid number!");

I've used expect() here to keep it simple, but in a production app, you'd probably want to loop until the user gives you a valid number instead of just crashing the program.

Should I just put all the math in the main function?

You could, but you shouldn't. Even for a tiny project like this, I always recommend splitting your logic from your I/O. If you keep your conversion formulas in their own functions, you can test them independently without having to manually type numbers into the console every single time you change a line of code.

I usually write my converters as pure functions that take a float and return a float. It makes the main function read like a story rather than a math textbook:

fn celsius_to_fahrenheit(c: f64) -> f64 {
    (c * 9.0 / 5.0) + 32.0
}

fn main() {
    let c = 25.0;
    let f = celsius_to_fahrenheit(c);
    println!("{}°C is {}°F", c, f);
}

What's the best way to handle someone typing "warm" instead of "25"?

This is where Rust's Result type really shines. As I mentioned earlier, parse() doesn't return a number; it returns a Result<f64, ParseFloatError>. If you use expect(), the program panics and dies. Not a great user experience.

Instead, I like to wrap the input logic in a loop and use a match statement. This allows the program to say "Hey, that's not a number, try again" without exiting. Here is the pattern I typically use for CLI tools:

let temp: f64 = loop {
    let mut input = String::new();
    io::stdin().read_line(&mut input).expect("Failed to read line");

    match input.trim().parse() {
        Ok(num) => break num,
        Err(_) => println!("That wasn't a number. Please try again!"),
    }
};

By using break num, we effectively "escape" the loop only once we have a valid value to assign to our variable.




📋 Practical Task

Exercise: Build a Tri-Unit Temperature Command Line Tool

Your task is to build a complete temperature converter that supports three scales: Celsius, Fahrenheit, and Kelvin. Instead of just one conversion, create a program that asks the user for the current temperature value and the unit it is currently in, then lets them choose which unit to convert it to.

  • Input Handling: Use a loop to ensure the program doesn't crash if the user enters a non-numeric value for the temperature.
  • Logic: Implement separate functions for each conversion path (e.g., kelvin_to_celsius, fahrenheit_to_kelvin, etc.).
  • User Interface: Provide a simple menu (e.g., "Press 1 for C, 2 for F, 3 for K") to determine the units.
  • Precision: Use f64 for all calculations to ensure accuracy.

Bonus challenge: Add a check to ensure the temperature entered isn't below Absolute Zero (-273.15°C) and warn the user if it is.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.