2014-11-13 12 views
13

Uwaga Kod w tym pytaniu odnosi się do wersji Rust przed 1.0, ale odpowiedzi zostały zaktualizowane dla Rust 1.0.Konwertuj wycinek łańcucha na int w Rust

Mam problem z przekonwertowaniem ciągu na liczbę całkowitą.

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

Wprowadzam numer na konsoli (na przykład 42), a mój program wyświetla None.

The documentation says że jest to normalna sytuacja, gdy ciąg jest źle sformatowany, ale co jest nie tak z moim 42?

Odpowiedz

17

Można zadzwonić str::parse(), ale trzeba się upewnić, że read_line działa. Musimy czytnika:

use std::io; 

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

stdin czyta globalny bufor, który obsługuje strumień wejściowy, a także realizuje BufRead cechę, która ma metodę read_line method. Wymaga to zmiennego String jako bufora wejściowego i odczytuje wszystkie bajty ze strumienia aż do osiągnięcia bajtu nowego wiersza i dołącza je do bufora. Metoda #expect() rozpakowuje Result; jeśli jest to Err, będzie panikował z wiadomością i przyczyną.

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

Mamy teraz tekst wejściowy, który chcemy przekonwertować na i32. To jest miejsce, w którym str::parse() będzie działać dla nas, o ile damy mu typ do parsowania. str::trim() jest konieczne, ponieważ read_line zawiera znak nowej linii bajt bufora

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

Nie jesteśmy jeszcze zrobione, wciąż musimy upewnić się, że udało nam się analizowany wejście przy użyciu dopasowywania wzorców. Cały kod trzeba zamienić oryginalny bufor wejściowy do całkowitej powierzchni użytkowej jest:

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

To kompiluje bez błędów lub ostrzeżeń.

8

Dane wejściowe zawierają znak końca linii, jak wyjaśniono w dokumentacji dla read_line. Powoduje to niepowodzenie from_str(). Korzystanie std::str::trim() i zmieniając w ten sposób:

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

w tym:

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

wydaje się działać.

3

Spróbuj tego:

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

Ta odpowiedź odnosi się do 'old_io' modułu, które nie są dostępne w Rust 1,0; ta odpowiedź nie jest już użyteczna. – Shepmaster

4

Z rdzy 1.14, The Rust Programming Language has this example:

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

Można też po prostu ponownie użyć tej samej nazwy zmiennej, a nowy typ będzie „cień” stary typ:

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

Do konwersji ciąg do liczby całkowitej używamy wykończenia i analizować. Metoda trim() w Strings eliminuje wszelkie białe znaki na początku i końcu naszego łańcucha.

Oznacza to, że jeśli wpiszemy 5 i powrócimy, przypuszczenie wygląda tak: 5 \ n. \ N oznacza "nową linię", klawisz Enter. trim() pozbywa się tego, pozostawiając nasz ciąg tylko 5.

Metoda parse() na łańcuchach przetwarza ciąg znaków na pewną liczbę. Ponieważ może on parsować różne liczby, musimy dać Rustowi wskazówkę co do dokładnego typu liczby, jaką chcemy. Stąd niech a_int: i32. Dwukropek (:) po odgadnięciu mówi Rustowi, że będziemy opisywać jego typ. i32 jest liczbą całkowitą, 32-bitową liczbą całkowitą. Używamy metody expect() do awarii, jeśli wystąpił błąd.

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

Ref

Powiązane problemy