1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
//! # Input and output manager
use std::{io, str};
/// Scanner is a struct that can be used to parse input from a reader.
///
/// # Examples
/// ```
/// use cp_template::iom::Scanner;
/// use std::io;
///
/// fn main() {
/// let mut scan = Scanner::new(io::stdin().lock());
/// let mut out = io::BufWriter::new(io::stdout().lock());
/// solve(&mut scan, &mut out);
/// }
///
/// fn solve<R: io::BufRead, W: io::Write>(scan: &mut Scanner<R>, out: &mut W) {
/// let n: usize = scan.tok();
/// let v: Vec<i32> = (0..n).map(|_| scan.tok()).collect();
/// writeln!(out, "{} {v:?}", n).ok();
/// }
/// ```
/// ```
/// use cp_template::iom::Scanner;
/// use std::io;
///
/// fn main() {
/// let mut scan = read_file("in.txt").unwrap();
/// let mut out = writer_file("out.txt").unwrap();
/// solve(&mut scan, &mut out);
/// }
///
/// fn solve<R: io::BufRead, W: io::Write>(scan: &mut Scanner<R>, out: &mut W) {
/// let n: usize = scan.tok();
/// let v: Vec<i32> = (0..n).map(|_| scan.tok()).collect();
/// writeln!(out, "{} {v:?}", n).ok();
/// }
/// ```
pub struct Scanner<R> {
reader: R,
buf_str: Vec<u8>,
buf_iter: str::SplitAsciiWhitespace<'static>,
}
impl<R: io::BufRead> Scanner<R> {
/// Creates a new Scanner.
/// # Examples
/// ```
/// let mut scan = Scanner::new(std::io::stdin().lock());
/// ```
/// ```
/// let file = std::fs::File::open(filename)?;
/// Scanner::new(io::BufReader::new(file))
/// ```
pub fn new(reader: R) -> Self {
Self {
reader,
buf_str: vec![],
buf_iter: "".split_ascii_whitespace(),
}
}
/// Reads a token.
/// # Panics
/// Panics if the token can't be parsed or the input is empty.
/// # Examples
/// ```
/// let mut scan = Scanner::new(std::io::stdin().lock());
/// let n: i32 = scan.tok();
/// ```
/// ```
/// let mut scan = Scanner::new(std::io::stdin().lock());
/// let n = scan.tok::<i32>();
/// ```
pub fn tok<T: str::FromStr>(&mut self) -> T {
loop {
if let Some(token) = self.buf_iter.next() {
return token.parse().ok().expect("Failed parse");
}
self.buf_str.clear();
self.reader
.read_until(b'\n', &mut self.buf_str)
.expect("Failed read");
self.buf_iter = unsafe {
let slice = str::from_utf8_unchecked(&self.buf_str);
std::mem::transmute(slice.split_ascii_whitespace())
}
}
}
}
/// Creates a Scanner from a file
/// # Examples
/// ```
/// let mut scan = file_reader("in.txt").unwrap();
/// let n: i32 = scan.tok();
/// ```
pub fn file_reader(filename: &str) -> io::Result<Scanner<io::BufReader<std::fs::File>>> {
let file = std::fs::File::open(filename)?;
Ok(Scanner::new(io::BufReader::new(file)))
}
/// Creates a BufWriter from a file
/// # Examples
/// ```
/// let n = 42;
/// let mut out = file_writer("out.txt").unwrap();
/// writeln!(out, "{}", n).ok();
/// ```
pub fn file_writer(filename: &str) -> io::Result<io::BufWriter<std::fs::File>> {
let file = std::fs::File::create(filename)?;
Ok(io::BufWriter::new(file))
}