How to read an integer input from the user in Rust 1.0? - input

Existing answers I've found are all based on from_str (such as Reading in user input from console once efficiently), but apparently from_str(x) has changed into x.parse() in Rust 1.0. As a newbie, it's not obvious how the original solution should be adapted taking this change into account.
As of Rust 1.0, what is the easiest way to get an integer input from the user?

Here is a version with all optional type annotations and error handling which may be useful for beginners like me:
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),
};
}

If you are looking for a way to read input for the purpose of competitive programming on websites like codeforces where you do not have access to text_io, this solution is for you.
I use the following macro to read different values from stdin:
#[allow(unused_macros)]
macro_rules! read {
($out:ident as $type:ty) => {
let mut inner = String::new();
std::io::stdin().read_line(&mut inner).expect("A String");
let $out = inner.trim().parse::<$type>().expect("Parsable");
};
}
#[allow(unused_macros)]
macro_rules! read_str {
($out:ident) => {
let mut inner = String::new();
std::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();
std::io::stdin().read_line(&mut inner).unwrap();
let $out = inner
.trim()
.split_whitespace()
.map(|s| s.parse::<$type>().unwrap())
.collect::<Vec<$type>>();
};
}
Use it as follows:
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);
}

Here are a few possibilities (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);
}
}
These spare you the ceremony of pattern matching without depending on extra libraries.

Probably the easiest part would be to use the text_io crate and write:
#[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);
}
If you need to read more than one value simultaneously, you might need to use Rust nightly.
See also:
Is there a way to check that the user entered an integer with text_io's read!() macro?

parse is more or less the same; it’s read_line that’s unpleasant now.
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."),
}
}

You can create an extension method if you want a simple syntax:
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(())
}

I would definitely use the file system Rust-Lang provides std::fs (See more here: https://doc.rust-lang.org/stable/std/fs/) But more particularly https://doc.rust-lang.org/stable/std/fs/fn.read_to_string.html
Let's say you just want to read input of a text file, try this :
use std::fs
or
use std::fs::read_to_string
fn main() {
println!("{}", fs::read_to_string("input.txt"));
}

you can try this piece of code
fn main() {
let mut line = String::new();
// read input line string and store it into line
std::io::stdin().read_line(&mut line).unwrap();
// convert line to integer
let number : i32 = line.trim().parse().unwrap();
println!("Your number {}",number);
}
now you can write a function for taking user input and use it everytime like below
fn main() {
let first_number = get_input();
let second_number = get_input();
println!("Summation : {}",first_number+second_number);
}
fn get_input() -> i32{
let mut line = String::new();
std::io::stdin().read_line(&mut line).unwrap();
let number : i32 = line.trim().parse().unwrap();
return number ;
}

Related

get structure header names with serde Serialize preserving order

Rust data structure.
This is my implementation to get headers preserving order:
use serde::{Deserialize, Serialize};
use csv::{Reader, Writer, StringRecord};
#[derive(Default, Debug, Deserialize, Serialize)]
pub struct Colunas {
#[serde(rename = "Arquivo Teste")]
arquivo: String,
#[serde(rename = "CNPJ dos Estabelecimentos")]
cnpj: Option<String>,
#[serde(rename = "Ano do Período de Apuração")]
ano: Option<usize>,
#[serde(rename = "Mês")]
m: u32,
}
impl Colunas {
fn get_headers(self) -> StringRecord {
// https://docs.rs/csv/1.0.0/csv/struct.Writer.html
let mut wtr = Writer::from_writer(vec![]);
wtr.serialize( Colunas::default() ).ok();
let colunas = String::from_utf8(wtr.into_inner().ok().unwrap()).ok().unwrap();
// split-a-string-in-rust
let mut lines = colunas.lines();
let first_line = lines.next().unwrap();
//println!("first_line: {:#?}", &first_line);
let vec: Vec<&str> = first_line.split(',').collect();
//println!("vec: {:#?}", vec);
//https://docs.rs/csv/1.0.0-beta.2/csv/struct.StringRecord.html
// https://docs.rs/csv/1.0.0/csv/struct.Reader.html
let mut rdr = Reader::from_reader("".as_bytes());
rdr.set_headers(StringRecord::from(vec));
let headers = rdr.headers().ok().unwrap();
//println!("headers: {:#?}", headers);
headers.clone()
}
}
fn main() {
let headers = Colunas::default().get_headers();
println!("headers: {:#?}", headers);
}
Is there any other more elegant and concise way?
Rust playground:
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=24cd9eeed8f5fbfa2abf0eff467a03a2
The output is:
headers: StringRecord(["Arquivo Teste", "CNPJ dos Estabelecimentos", "Ano do Período de Apuração", "Mês"])
I don't know of any concise and elegant way. But I can give you concise via a trip through serde_json::Value
serde_json::to_value(&Colunas::default())
.unwrap()
.as_object()
.unwrap()
.keys()
.collect()
(Enabling the preserve_order feature on serde_json should preserve the order of the fields in the struct.)
As for elegant, one part I consider inelegant is that you have to make Colunas impl Default for this. This can be avoided with a custom deserializer, which has access to the structure without ever needing a value.
struct FieldTracingDeserializer<'a> {
fields: &'a mut Vec<&'static str>,
}
impl<'de, 'a> serde::Deserializer<'de> for FieldTracingDeserializer<'a> {
type Error = serde::de::value::Error;
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where
V: serde::de::Visitor<'de>,
{
panic!("Only works for structs");
}
serde::forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map enum identifier ignored_any
}
fn deserialize_struct<V>(
self,
_name: &'static str,
fields: &'static [&'static str],
_visitor: V,
) -> Result<V::Value, Self::Error>
where
V: serde::de::Visitor<'de>,
{
// Would be cleaner to return fields through a custom error struct.
// But also more work.
self.fields.extend_from_slice(fields);
Err(serde::de::Error::custom("success"))
}
}
let mut headers = vec![];
Colunas::deserialize(FieldTracingDeserializer {
fields: &mut headers,
})
.ok();
headers.into_iter().collect()
I don't really think this can be called elegant… There are however crates that implement this exact functionality (e.g. serde-aux):
serde_aux::serde_introspection::serde_introspect::<Colunas>()

Rust read_line() delays stdout buffer until end of scope

I'm trying to get user input from the command line in a more visually pleasing way by printing ">> " before reading what the user types in. Then I simply print what was typed in.
use std::io;
fn get_input() -> Result<String, io::Error> {
print!(">> ");
let mut result = String::new();
io::stdin().read_line(&mut result)?;
Ok(result)
}
fn main() {
let string = get_input().expect("couldn't read input");
let string = string.trim();
println!("== {}", string);
}
When running the above program and typing "test" into the terminal, why is the output of the code snippet this:
test
>> == test
and not this?
>> test
== test
Writing to stdout is generally line-buffered, so when using print!() you need to flush() stdout afterwards before reading from stdin.
use std::io::Write;
fn get_input() -> Result<String, io::Error> {
print!(">> ");
io::stdout().flush()?;
let mut result = String::new();
io::stdin().read_line(&mut result)?;
Ok(result)
}

How can I automatically implement FromIterator?

I have written a trait that specifies some methods similar to those of Vec:
pub trait Buffer {
type Item;
fn with_capacity(c: usize) -> Self;
fn push(&mut self, item: Self::Item);
}
I would like to implement FromIterator for all types that implement Buffer, as follows:
impl<T> iter::FromIterator<T::Item> for T
where T: Buffer
{
fn from_iter<I>(iter: I) -> Self
where I: IntoIterator<Item = T>
{
let mut iter = iter.into_iter();
let (lower, _) = iter.size_hint();
let ans = Self::with_capacity(lower);
while let Some(x) = iter.next() {
ans.push(x);
}
ans
}
}
The compiler won't let me:
error[E0210]: type parameter `T` must be used as the type parameter
for some local type (e.g. `MyStruct<T>`); only traits defined in the
current crate can be implemented for a type parameter
I think I understand the error message; it is preventing me from writing code that is incompatible with possible future changes to the standard library.
The only way around this error appears to be to implement FromIterator separately for every type for which I implement Buffer. This will involve copying out exactly the same code many times. Is there a a way to share the same implementation between all Buffer types?
You can't implement a trait from another crate for an arbitrary type, only for a type from your crate. However, you can move the implementation to a function and reduce amount of duplicated code:
fn buffer_from_iter<I, B>(iter: I) -> B
where I: IntoIterator<Item = B::Item>,
B: Buffer
{
let mut iter = iter.into_iter();
let (lower, _) = iter.size_hint();
let mut ans = B::with_capacity(lower);
while let Some(x) = iter.next() {
ans.push(x);
}
ans
}
struct S1;
impl Buffer for S1 {
type Item = i32;
fn with_capacity(c: usize) -> Self { unimplemented!() }
fn push(&mut self, item: Self::Item) { unimplemented!() }
}
impl std::iter::FromIterator<<S1 as Buffer>::Item> for S1 {
fn from_iter<I>(iter: I) -> Self
where I: IntoIterator<Item = <S1 as Buffer>::Item>
{
buffer_from_iter(iter)
}
}
This implementation of FromIterator can be wrapped into a macro to further reduce code duplication.

How to avoid going to new line with stdin in Rust

I have this code:
fn main() {
let mut stdin = io::stdin();
let input = &mut String::new();
loop {
input.clear();
print!("Your age: ");
stdin.read_line(input);
print!("{}", input);
}
}
So when I input something, the programs returns "Your age:" plus my input.
But when I run the program I don't want to write the input in a new line.
To do something like that in Python, I can write:
var = input("Your age: ")
How can I avoid going to a new line? I'm sure it's simple but I really can't realize how to do that, I tried a lot of different stuff...
You need to flush stdout before reading the line:
use std::io::{self, Write};
fn main() {
let mut stdin = io::stdin();
let input = &mut String::new();
loop {
input.clear();
print!("Your age: ");
io::stdout().flush();
stdin.read_line(input);
print!("{}", input);
}
}
From the print! documentation:
Note that stdout is frequently line-buffered by default so it may be necessary to use io::stdout().flush() to ensure the output is emitted immediately.

How do I return an error from a scoped_threadpool thread?

I have some code that uses scoped_threadpool a bit like this:
extern crate scoped_threadpool;
use scoped_threadpool::Pool;
use std::error::Error;
fn main() {
inner_main().unwrap();
}
fn inner_main() -> Result<(), Box<Error>> {
let mut pool = Pool::new(2);
pool.scoped(|scope| {
scope.execute(move || {
// This changed to become fallible
fallible_code();
});
});
Ok(())
}
fn fallible_code() -> Result<(), Box<Error + Send + Sync>> {
Err(From::from("Failing"))
}
The fallible_code function recently changed to return a Result, and I'd like to propagate the error outside of the pool.scoped block. However, the signature of Scope::execute doesn't allow for a return value:
fn execute<F>(&self, f: F)
where F: FnOnce() + Send + 'scope
I am using scoped_threadpool 0.1.7.
I don't know if it's a particularly idiomatic method, but one method that at least works is assigning to a captured variable.
let mut pool = Pool::new(2);
let mut ret = Ok(());
pool.scoped(|scope| {
scope.execute(|| {
ret = fallible_code();
});
});
ret.map_err(|x| x as Box<Error>)
Obviously you'd need to make ret an Option or so if there is no trivial default. If the inner closure must be move, you'll need to make ret_ref = &mut ret explicit.