Convert string slice to int in Rust

12,444

Solution 1

You can call str::parse(), but you need to make sure that read_line is working. We need a reader:

use std::io;
fn main() {
    let reader = io::stdin();
}

stdin reads the global buffer that handles the input stream and also implements the BufRead trait which has the read_line method method. This takes a mutable String as an input buffer and reads all bytes from the stream until a newline byte is reached and appends them to the buffer. The #expect() method unwraps the Result; if it is an Err it will panic with the message and the cause.

use std::io;
fn main() {
    let reader = io::stdin();
    let mut input_text = String::new();
    reader.read_line(&mut input_text).expect("failed to read line");
}

We now have the input text that we want to convert into an i32. This is where str::parse() will work for us, as long as we give it a type to parse to. str::trim() is necessary because read_line includes the newline byte the buffer

use std::io;
fn main() {
    let reader = io::stdin();
    let mut input_text = String::new();
    reader.read_line(&mut input_text).expect("failed to read line");
    let input = input_text.trim().parse::<i32>();
}

We're not done yet, we still need to ensure that we successfully parsed the input using pattern matching. All the code you need to convert your original input buffer into a usable integer is:

use std::io;
fn main() {
    let reader = io::stdin();
    let mut input_text = String::new();
    reader.read_line(&mut input_text).expect("failed to read line");
    let input_opt = input_text.trim().parse::<i32>();
    let input_int = match input_opt {
        Ok(input_int) => input_int,
        Err(e) => {
            println!("please input a number ({})", e);
            return;
        }
    };
    println!("{}", input_int);
}

This compiles without errors or warnings.

Solution 2

The input includes a newline at the end, as explained in the documentation for read_line. This causes from_str() to fail. Using std::str::trim() and changing this:

let input: Result<i32, _> = input_text.parse();

into this:

let input: Result<i32, _> = input_text.trim().parse();

seems to work.

Solution 3

As of Rust 1.14, The Rust Programming Language has this example:

let guess: u32 = guess.trim().parse()
    .expect("Please type a number!");

You can also just use the same variable name again and the new type will "shadow" the old type:

use std::io;
fn main() {
    let mut input_text = String::new();
    io::stdin()
        .read_line(&mut input_text)
        .expect("failed to read line");
    let input: u32 = input_text.trim().parse()
        .expect("Please type a number!");
}

Solution 4

Try this:

fn main() {
    let input_text = std::old_io::stdin()
        .read_line()
        .ok()
        .expect("failed to read line");
    let input_number: Option<i32> = input_text.trim().parse().ok();
    let number = match input_number{
        Some(num) => num,
        None => {
            println!("Wrong input data! Input a number.");
            return;
        }
    };
    println!("{}", number);
}
Share:
12,444

Related videos on Youtube

Glen Swift
Author by

Glen Swift

I dare you, i double dare you, say what again

Updated on July 02, 2022

Comments

  • Glen Swift
    Glen Swift 5 months

    Note The code in this question pertains to a version of Rust before 1.0 but the answers have been updated for Rust 1.0.

    I have trouble converting a string to an integer.

    fn main() {
        let input_text = io::stdin()
            .read_line()
            .ok()
            .expect("failed to read line");
        let input: Option<int> = from_str(input_text.as_slice());
        println!("{}", input);
    }
    

    I enter a number on the console (42 for example) and my program prints None.

    The documentation says that that is a normal situation when the string is ill-formatted, but what's wrong with my 42?

  • Shepmaster
    Shepmaster almost 6 years
    This answer refers to the old_io module, which is not available in Rust 1.0; this answer is no longer useful.

Related