4 releases
0.2.0 | Jun 2, 2023 |
---|---|
0.1.2 | Jan 13, 2023 |
0.1.1 | Jan 12, 2023 |
0.1.0 | Jan 11, 2023 |
#1527 in Text processing
44 downloads per month
28KB
534 lines
token-read
This is a simple crate that allows for easy parsing of whitespace delimited files.
It is primarily intended for competitive programming, where such files are commonly used as inputs due to being easy to parse in C and C++. This crate aims to bring this ease to Rust.
Examples
For complete programs, see the examples in the source repository.
Initialization
A TokenReader
can be constructed from any type implementing BufRead
, such as a file, standard input or a byte slice.
The easiest way to handle errors is to use anyhow.
use std::io::stdin;
use anyhow::Result;
use token_read::TokenReader;
fn main() -> Result<()> {
let mut input = TokenReader::new(stdin().lock());
// Do IO and computation
Ok(())
}
Reading one or more values
A tuple of one or more values of any type implementing FromStr
can be read using the line
function.
let (budget, ): (u64, ) = input.line()?;
let (product, cost): (String, u64) = input.line()?;
Sample input
10000
Sandwich 80
Reading a raw line
In order to read a line without any modifications, you can use the line_raw
function.
let sentence: String = input.line_raw()?;
Sample input
All human beings are born free and equal in dignity and rights.
Reading a collection of values
The line
function can also be used to read a variable amount values of a type implementing FromStr
into most standard collections.
let temperatures: Vec<f64> = input.line()?;
let allowed_letters: HashSet<char> = input.line()?;
Sample input
18.7 19.2 19.4 18.9
A B E I J M N
Reading several lines
The take
function can be used to create an iterator consuming a specific number of lines. You can use it to make a simple for
loop.
let (city_count, ): (usize, ) = input.line()?;
for city in input.take(city_count) {
let (name, population): (String, u64) = city?;
}
Alternatively, it can be collected into any data structure.
let (city_count, ): (usize, ) = input.line()?;
let cities: Vec<(String, u64)> = input.take(city_count).collect::<Result<_, _>>()?;
In cases where the input doesn't need to be stored in memory, take_count
can be used instead, as it allows larger line counts than fit in a usize
:
let (city_count, ): (u64, ) = input.line()?;
for city in input.take_count(city_count) {
let (name, population): (String, u64) = city?;
}
Sample input
3
Prague 1309000
New York 8468000
Tokio 13960000
Installation
This crate is available from crates.io. To install, simply run:
cargo add token-read
Dependencies
~295–750KB
~17K SLoC