2014-11-13 19 views
13

Nota Il codice in questa domanda si riferisce a una versione di Rust prima di 1.0 ma le risposte sono state aggiornate per Rust 1.0.Converti sezione stringa in int in Rust

Ho difficoltà a convertire una stringa in un numero intero.

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); 
} 

ho immettere un numero sulla console (42 per esempio) e il mio programma stampa None.

The documentation says che si tratta di una situazione normale quando la stringa è mal formattata, ma cosa c'è di sbagliato con il mio 42?

risposta

17

È possibile chiamare str::parse(), ma è necessario fare in modo che read_line sta lavorando. Abbiamo bisogno di un lettore:

use std::io; 

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

stdin legge il buffer globale che gestisce il flusso di input e anche implementa il BufRead tratto che ha il metodo read_line method. Questo accetta un String mutabile come buffer di input e legge tutti i byte dal flusso finché non viene raggiunto un nuovo byte e li aggiunge al buffer. Il metodo #expect() srotola lo Result; se è un Err verrà messo in panico con il messaggio e la causa.

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"); 
} 

ora abbiamo il testo di input che vogliamo convertire in un i32. Questo è dove str::parse() funzionerà per noi, a patto che gli diamo un tipo da analizzare. str::trim() è necessario perché read_line include il byte a capo del 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>(); 
} 

Noi non abbiamo ancora finito, abbiamo ancora bisogno di assicurare che abbiamo analizzato con successo l'ingresso utilizzando pattern matching. Tutto il codice è necessario convertire il buffer di input originale in un intero utilizzabile è:

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); 
} 

Questo compila senza errori o avvisi.

8

L'input include una nuova riga alla fine, come spiegato nella documentazione per read_line. Ciò causa l'errore from_str(). Utilizzando std::str::trim() e cambiare questo:

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

in questo:

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

sembra funzionare.

3

Prova questo:

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); 
} 
+0

Questa risposta indica il modulo 'old_io', che non è disponibile in Rust 1.0; questa risposta non è più utile. – Shepmaster

4

A partire da Rust 1.14, The Rust Programming Language has this example:

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

È anche possibile utilizzare di nuovo lo stesso nome della variabile e il nuovo tipo sarà "ombra" del vecchio tipo:

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!"); 
} 
-1

Per convertire la stringa a intero usiamo assetto e analizzare. Il metodo trim() su Strings eliminerà qualsiasi spazio bianco all'inizio e alla fine della nostra stringa.

Questo significa che se digitiamo 5 e premete Invio, indovinare assomiglia a questo: 5 \ n. \ N rappresenta 'newline', il tasto invio. trim() si libera di questo, lasciando la nostra stringa con solo il metodo 5.

Il parse() su stringhe analizza una stringa in una sorta di numero. Poiché può analizzare una varietà di numeri, dobbiamo dare a Rust un suggerimento sul tipo esatto di numero che vogliamo. Quindi, lascia a_int: i32. I due punti (:) dopo l'indovinello dicono a Rust che annoteremo il suo tipo. i32 è un intero, numero trentadue-bit. Usiamo il metodo expect() per bloccarsi in caso di errore.

let a_int: i32 = input_1.trim().parse() 
.ok() 
.expect("Please type a number!"); 

Rif: