Как я могу прочитать одну строку из стандартного ввода?

Я прошу эквивалент fgets() в C.

let line = ...;
println!("You entered: {}", line);

Я прочитал Как читать пользовательский ввод в Rust?, но спрашивает, как читать несколько строк; Я хочу только одну строчку.

Я также читаю Как мне прочитать одну строку из стандартного ввода?, но я не уверен, что она ведет себя как fgets() или sscanf("%s",...).

Ответ 1

В Как читать пользовательский ввод в Rust? вы можете увидеть, как перебирать все строки:

use std::io::{self, BufRead};

fn main() {
    let stdin = io::stdin();
    for line in stdin.lock().lines() {
        println!("{}", line.unwrap());
    }
}

Вы также можете выполнить итерацию вручную без цикла for:

use std::io::{self, BufRead};

fn main() {
    let stdin = io::stdin();
    let mut iterator = stdin.lock().lines();
    let line1 = iterator.next().unwrap().unwrap();
    let line2 = iterator.next().unwrap().unwrap();
}

Вы не можете написать одну строку, чтобы делать то, что вы хотите. Но следующее читает одну строку (и это точно такой же ответ, как в Как мне прочитать одну строку из стандартного ввода?):

use std::io::{self, BufRead};

fn main() {
    let stdin = io::stdin();
    let line1 = stdin.lock().lines().next().unwrap().unwrap();
}

Вы также можете использовать text_io ящик для очень простого ввода:

#[macro_use] extern crate text_io;

fn main() {
    // reads until a \n is encountered
    let line: String = read!("{}\n");
}

Ответ 2

Если вам действительно нужен эквивалент fgets, тогда @Gerstmann прав, вы должны использовать Stdin::read_line. Этот метод принимает буфер, в котором у вас больше возможностей для ввода строки:

use std::io::{self, BufRead};

fn main() {
    let mut line = String::new();
    let stdin = io::stdin();
    stdin.lock().read_line(&mut line).unwrap();
    println!("{}", line)
}

В отличие от C, вы не можете случайно перехватить буфер; он будет автоматически изменен, если входная строка слишком велика.

Ответ от @oli_obk - ker - это идиоматическое решение, которое вы увидите большую часть времени. В нем строка управляется для вас, а интерфейс намного чище.

Ответ 3

Прочитайте одну строку из stdin:
std::io::stdin().read_line(&mut line)?;

Использование неявной синхронизации:

use std::io;
fn main() -> io::Result<()> {
    let mut line = String::new();
    io::stdin().read_line(&mut line)?;

    println!("You entered: {}", line);
    Ok(())
}

Использование явной синхронизации:

use std::io::{self, BufRead};

fn main() -> io::Result<()> {
    let stdin = io::stdin();
    let mut handle = stdin.lock();

    let mut line = String::new();
    handle.read_line(&mut line)?;

    println!("You entered: {}", line);
    Ok(())
}

Если вас интересует количество байтов, например n, используйте:
let n = handle.read_line(&mut line)?;
или
let n = io::stdin().read_line(&mut line)?;

Попробуйте это:

use std::io;
fn main() -> io::Result<()> {
    let mut line = String::new();
    let n = io::stdin().read_line(&mut line)?;

    println!("{} bytes read", n);
    println!("You entered: {}", line);
    Ok(())
}

см. документ