web-dev-qa-db-fra.com

Comment lire une entrée entière de l'utilisateur en Rust 1.0?

Les réponses existantes que j'ai trouvées sont toutes basées sur from_str (Comme Lecture efficace des entrées utilisateur depuis la console ), mais apparemment from_str(x) est devenu x.parse() in Rust 1.0. En tant que débutant, il n'est pas évident de savoir comment la solution originale devrait être adaptée en tenant compte de ce changement.

Depuis Rust 1.0, quelle est la manière la plus simple d'obtenir une entrée entière de l'utilisateur?

Voici une version avec toutes les annotations de type facultatives et la gestion des erreurs qui peuvent être utiles pour les débutants comme moi:

use std::io;

fn main() {
    let mut input_text = String::new();
    io::stdin()
        .read_line(&mut input_text)
        .expect("failed to read from stdin");

    let trimmed = input_text.trim();
    match trimmed.parse::<u32>() {
        Ok(i) => println!("your integer input: {}", i),
        Err(..) => println!("this was not an integer: {}", trimmed),
    };
}
36
Michael

La partie la plus simple serait probablement d'utiliser la caisse text_io et d'écrire:

#[macro_use]
extern crate text_io;

fn main() {
    // read until a whitespace and try to convert what was read into an i32
    let i: i32 = read!();
    println!("Read in: {}", i);
}

Si vous devez lire plusieurs valeurs simultanément, vous devrez peut-être utiliser Rust nightly.

Voir également:

11
Daniel Fath

Voici quelques possibilités (Rust 1.7):

use std::io;

fn main() {
    let mut n = String::new();
    io::stdin()
        .read_line(&mut n)
        .expect("failed to read input.");
    let n: i32 = n.trim().parse().expect("invalid input");
    println!("{:?}", n);

    let mut n = String::new();
    io::stdin()
        .read_line(&mut n)
        .expect("failed to read input.");
    let n = n.trim().parse::<i32>().expect("invalid input");
    println!("{:?}", n);

    let mut n = String::new();
    io::stdin()
        .read_line(&mut n)
        .expect("failed to read input.");
    if let Ok(n) = n.trim().parse::<i32>() {
        println!("{:?}", n);
    }
}

Ceux-ci vous épargnent la cérémonie de correspondance de motifs sans dépendre de bibliothèques supplémentaires.

8
qed

parse est plus ou moins identique; c'est read_line c'est désagréable maintenant.

use std::io;

fn main() {
    let mut s = String::new();
    io::stdin().read_line(&mut s).unwrap();

    match s.trim_right().parse::<i32>() {
        Ok(i) => println!("{} + 5 = {}", i, i + 5),
        Err(_) => println!("Invalid number."),
    }
}
4
Ry-

Si vous cherchez un moyen de lire les entrées à des fins de programmation compétitive sur des sites Web comme codechef ou codeforces où vous n'avez pas accès à text_io.

Ce n'est pas une nouvelle façon de lire plutôt une mentionnée dans les réponses ci-dessus, je viens de la modifier en fonction de mes besoins.

J'utilise la macro suivante pour lire depuis stdin les différentes valeurs:

use std::io;

#[allow(unused_macros)]
macro_rules! read {
    ($out:ident as $type:ty) => {
        let mut inner = String::new();
        io::stdin().read_line(&mut inner).expect("A String");
        let $out = inner.trim().parse::<$type>().expect("Parseble");
    };
}

#[allow(unused_macros)]
macro_rules! read_str {
    ($out:ident) => {
        let mut inner = String::new();
        io::stdin().read_line(&mut inner).expect("A String");
        let $out = inner.trim();
    };
}

#[allow(unused_macros)]
macro_rules! read_vec {
    ($out:ident as $type:ty) => {
        let mut inner = String::new();
        io::stdin().read_line(&mut inner).unwrap();
        let $out = inner
            .trim()
            .split_whitespace()
            .map(|s| s.parse::<$type>().unwrap())
            .collect::<Vec<$type>>();
    };
}

En principal


fn main(){
   read!(x as u32);
   read!(y as f64);
   read!(z as char);
   println!("{} {} {}", x, y, z);

   read_vec!(v as u32); // Reads space separated integers and stops when newline is encountered.
   println!("{:?}", v);
}

REMARQUE: je ne suis pas Rust Expert, si vous pensez qu'il existe un moyen de l'améliorer, veuillez me le faire savoir. Cela m'aidera, merci.

3
coder3101

Vous pouvez créer une méthode d'extension si vous voulez une syntaxe simple:

use std::error::Error;
use std::io;
use std::str::FromStr;

trait Input {
    fn my_read<T>(&mut self) -> io::Result<T>
    where
        T: FromStr,
        T::Err: Error + Send + Sync + 'static;
}

impl<R> Input for R where R: io::Read {
    fn my_read<T>(&mut self) -> io::Result<T>
    where
        T: FromStr,
        T::Err: Error + Send + Sync + 'static,
    {
        let mut buff = String::new();
        self.read_to_string(&mut buff)?;

        buff.trim()
            .parse()
            .map_err(|e| io::Error::new(io::ErrorKind::InvalidInput, e))
    }
}

// Usage:

fn main() -> io::Result<()> {
    let input: i32 = io::stdin().my_read()?;

    println!("{}", input);

    Ok(())
}
1
Boiethios

J'utiliserais certainement le système de fichiers que Rust-Lang fournit std::fs (Voir plus ici: https://doc.Rust-lang.org/stable/std/fs/ ) Mais plus particulièrement https: //doc.Rust-lang. org/stable/std/fs/fn.read_to_string.html

Supposons que vous vouliez simplement lire l'entrée d'un fichier texte, essayez ceci:

use std::fs
or
use std::fs::read_to_string

fn main() {
    println!("{}", fs::read_to_string("input.txt"));   
}
0
rust