Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert string slice to int in Rust

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?

like image 752
Glen Swift Avatar asked Nov 13 '14 22:11

Glen Swift


People also ask

What does parse () do in Rust?

Strings can be converted to integers in Rust with the parse() function. We can parse just parts of strings with get(). With the turbofish operator, we can parse to specific types.

What is a string slice in Rust?

A string slice is a reference to part of a String , and it looks like this: let s = String::from("hello world"); let hello = &s[0.. 5]; let world = &s[6.. 11]; Rather than a reference to the entire String , hello is a reference to a portion of the String , specified in the extra [0..

How do you convert a string from u8 to Rust?

Function core::str::from_utf81.0. 0 [−] [src] Converts a slice of bytes to a string slice. A string slice ( &str ) is made of bytes ( u8 ), and a byte slice ( &[u8] ) is made of bytes, so this function converts between the two. Not all byte slices are valid string slices, however: &str requires that it is valid UTF-8.


1 Answers

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.

like image 194
rouma7 Avatar answered Sep 16 '22 15:09

rouma7