Rust: с нуля до своего органайзера Урок 34 из 35
Ввод из терминала: строка, пустой ответ и конец потока
Урок 34. Прочитать название задачи и различить пустую строку, конец ввода и ошибку чтения.
Текст переведён с помощью ИИ.
Предварительно: уроки 4, 21–22, 25 и 31–33. Если Result ещё неясен, повторите урок 32.
Образ и опорная карта
Представьте стойку приёма: человек может написать название, оставить строку пустой или закрыть окно приёма. Это три разных события. Стандартный ввод — поток текста, который программа получает обычно из терминала; другой процесс также может передать туда текст. Конец потока (EOF) означает, что больше данных не будет. Пустая строка после нажатия Enter — введённая строка, а не конец потока. Образ ограничен: read_line сообщает число байтов, а не видимых букв, и может вернуть ошибку чтения.
Пустой String → read_line(&mut ...) → Ok(0) / Ok(число) / Err → trim() → ответ. std::io::stdin() получает стандартный ввод; std::io — путь к средствам ввода и вывода стандартной библиотеки, :: из урока 28 связывает части пути. String::new() создаёт пустую строку. read_line(&mut line) добавляет введённую строку в неё, поэтому нужна изменяемая ссылка. Метод возвращает Result<usize, std::io::Error>: Ok(0) означает конец потока, Ok с положительным числом — сколько байтов прочитано, Err — чтение не удалось. usize — тип размера и индекса из уроков о массивах. trim() даёт &str без пробелов и перевода строки по краям; внутри названия пробелы сохраняются. Если после этого текст равен "", название пустое.
Первый ответ пользователя
Сохраните прежний src/main.rs проекта organizer, замените весь файл и выполните cargo run рядом с Cargo.toml. Другие файлы и зависимости не меняются. После приглашения введите Чтение и нажмите Enter: программа покажет Задача: Чтение. В терминале набранные вами символы могут отображаться отдельно; это не вывод println!.
Для автоматической проверки пример запускается с уже закончившимся пустым вводом. Поэтому блок результата ниже показывает ветку EOF; она воспроизводится, если передать программе пустой поток. При обычном интерактивном запуске вводите название, чтобы проверить другую ветку.
fn main() {
let mut line = String::new();
println!("Введите название:");
match std::io::stdin().read_line(&mut line) {
Ok(0) => println!("Ввод закончился"),
Ok(_) => {
let title = line.trim();
if title == "" {
println!("Пустое название");
} else {
println!("Задача: {title}");
}
}
Err(_) => println!("Не удалось прочитать ввод"),
}
}
Введите название:
Ввод закончился
Нажатие Enter без текста идёт в Ok(_), после trim() название пустое и появляется Пустое название. Конец ввода идёт в Ok(0); повторять чтение после него без новой причины не нужно. trim() также убирает пробелы в начале и конце названия, что может быть желательным для задач, но для других данных правило надо выбирать отдельно. Обработка здесь одной строки — ещё не полный цикл команд органайзера.
Нельзя считать EOF пустым названием
Проверьте три наблюдения отдельно: введённое Чтение, пустая строка с Enter и отсутствие данных в потоке. Если смешать Ok(0) и Ok(_), программа начнёт просить название даже тогда, когда источник ввода уже закрыт. Ошибку Err тоже не превращайте молча в пустую задачу. Для пользовательских данных не применяйте .unwrap() к read_line.
Проверка понимания
- Почему
lineобъявлена сmut? - Что отличает
Ok(0)от Enter на пустой строке? - Удаляет ли
trim()пробел между двумя словами?
Проверьте: read_line меняет строку; Ok(0) — конец потока, Enter даёт прочитанный перевод строки; внутренний пробел остаётся. Воспроизведите опорную карту без страницы.
Задание
Обязательное. Прочитайте одно название из стандартного ввода. При EOF покажите Больше ввода нет, при пустом после trim() названии — Нужно название, при удачном непустом вводе — Добавить: НАЗВАНИЕ, где название взято из ввода. При Err покажите Ошибка чтения. Испытайте все три обычных случая; для EOF завершите поток ввода способом вашей оболочки или подайте пустой файл.
Граница. Введите Мой план и убедитесь, что пробел между словами остаётся.
Подсказка
В match сначала поставьте Ok(0), затем Ok(_), затем Err(_). Внутри Ok(_) получите let title = line.trim(); и сравните его с пустым текстом.
Эталон после попытки
fn main() {
let mut line = String::new();
match std::io::stdin().read_line(&mut line) {
Ok(0) => println!("Больше ввода нет"),
Ok(_) => {
let title = line.trim();
if title == "" {
println!("Нужно название");
} else {
println!("Добавить: {title}");
}
}
Err(_) => println!("Ошибка чтения"),
}
}
Больше ввода нет
Эталонный вывод показан для пустого потока; при Мой план будет Добавить: Мой план. Официальная документация read_line.
Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом
Комментарии (0)
Войдите, чтобы оставить комментарий →
Пока нет комментариев. Будьте первым.