Преобразование фрагмента строки в int в Rust
Примечание Код в этом вопросе относится к версии Rust до 1.0, но ответы были обновлены для Rust 1.0.
У меня проблема с преобразованием строки в целое число.
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);
}
Я ввожу номер на консоли (например, 42), и моя программа печатает None
.
В документации говорится, что это нормальная ситуация, когда строка плохо отформатирована, но что не так с моей 42
?
Ответы
Ответ 1
Вы можете вызвать str::parse()
, но вам нужно убедиться, что работает read_line
. Нам нужен читатель:
use std::io;
fn main() {
let reader = io::stdin();
}
stdin
читает глобальный буфер, который обрабатывает входной поток, а также реализует BufRead
, который имеет метод read_line
method. Это принимает изменяемый String
в качестве входного буфера и считывает все байты из потока до тех пор, пока не будет достигнут байт новой строки и добавит их в буфер. Метод #expect()
распаковывает Result
; если это Err
, он будет паниковать с сообщением и причиной.
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");
}
Теперь у нас есть текст ввода, который мы хотим преобразовать в i32
. Здесь str::parse()
будет работать для нас, если мы дадим ему тип для синтаксического анализа. str::trim()
необходимо, потому что read_line
включает в себя байт новой строки в буфере
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>();
}
Мы еще не закончили, нам все равно нужно убедиться, что мы успешно проанализировали входные данные, используя сопоставление шаблонов. Весь код, необходимый для преобразования исходного входного буфера в полезное целое число:
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);
}
Это компилируется без ошибок или предупреждений.
Ответ 2
Ввод включает в себя новую строку в конце, как описано в документации для read_line
. Это приведет к сбою from_str()
. Используя std::str::trim()
и изменив это:
let input: Result<i32, _> = input_text.parse();
в это:
let input: Result<i32, _> = input_text.trim().parse();
похоже, работает.
Ответ 3
По состоянию на Rust 1.14 Язык программирования ржавчины имеет этот пример:
let guess: u32 = guess.trim().parse()
.expect("Please type a number!");
Вы также можете снова использовать одно и то же имя переменной, и новый тип будет "теневым" старым типом:
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!");
}
Ответ 4
Попробуйте следующее:
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);
}
Ответ 5
Для преобразования строки в целое мы используем trim и parse. Метод trim() в Strings удалит любые пробелы в начале и конце нашей строки.
Это означает, что если мы наберем 5 и нажмем return, предположим, что выглядит так: 5\n.\N представляет 'новую строку, клавишу ввода. trim() избавится от этого, оставив нашу строку только с 5.
Метод parse() в строках анализирует строку на некоторый номер. Поскольку он может анализировать множество чисел, нам нужно дать Rust подсказку о точном типе нужного числа. Следовательно, пусть a_int: i32. Двоеточие (:) после угадывания говорит, что Руст собирался аннотировать его тип. i32 - целое число тридцать два бита. Мы используем метод expect() для сбоя, если theres ошибка.
let a_int: i32 = input_1.trim().parse()
.ok()
.expect("Please type a number!");
Ref: