Rust input/output: Difference between revisions

From wikinotes
(Created page with " = print = <blockquote> <syntaxhighlight lang="rust"> println!("abc"); // string interpolation println!("Hello, {}", "alex"); println!("Hello {0}. Hey {0} did you see {1}?",...")
 
 
(18 intermediate revisions by the same user not shown)
Line 1: Line 1:
= Documentation =
<blockquote>
{| class="wikitable"
|-
| <code>std::fs</code> || https://doc.rust-lang.org/std/fs/index.html
|-
|}
</blockquote><!-- Documentation -->
= Stdin, Stdout, Stderr =
<blockquote>
== Stdout/Stderr ==
<blockquote>
<syntaxhighlight lang="rust">
println!("out");  // write to stdout
eprintln!("err");  // write to stderr
</syntaxhighlight>
</blockquote><!-- Stdout/Stderr -->


= print =
== Stdin ==
<blockquote>
<blockquote>
{{ NOTE |
rust nightly has a [https://doc.rust-lang.org/std/io/trait.IsTerminal.html std::io::IsTerminal] that checks if the stream is a pipe or a tty.<br>
but besides this there is no builtin way to verify this.<br>
you can do it manually with [[rust libc]], but the most portable way is to use [[rust atty]].
}}
read from stdin
<syntaxhighlight lang="rust">
extern crate atty;
use std::io;
use std::io::BufRead;
/// read big files
fn buffered_read_all_stdin() {
    // don't read unless stdin is a pipe
    if atty::is(atty::Stream::Stdin) {
        return
    }
    let stdin = io::stdin();
    let handle = stdin.lock();
    let lines: Vec<String> = handle
        .lines()
        .map(|res| res.unwrap_or_default())
        .collect();
    print!("START\n{}\nFINISH\n", lines.join("\n"));
}
</syntaxhighlight>
manual buffered read
<syntaxhighlight lang="rust">
<syntaxhighlight lang="rust">
println!("abc");
extern crate atty;
use std::io::Read;
use std::str;


// string interpolation
/// like `tail -f`
println!("Hello, {}", "alex");
fn manually_buffered_read_stdin() {
println!("Hello {0}. Hey {0} did you see {1}?", "alex", "movie");
    // don't read unless stdin is a pipe
println!("Hello {person}. Did you see {thing}?", person="alex", thing="movie");
    if atty::is(atty::Stream::Stdin) {
        return
    }
 
    let mut buffer: [u8; 1024] = [0; 1024];
    let stdin = io::stdin();
    let mut handle = stdin.lock();
 
    loop {
        let bytes_read = handle
            .read(&mut buffer[..])
            .unwrap_or(0);
 
        // reached EOF
        if bytes_read == 0 {
            break;
        }
        print!("{}", str::from_utf8(&buffer).unwrap());
    }
}
</syntaxhighlight>
</blockquote><!-- Stdin -->
</blockquote><!-- Stdin, Stdout, Stderr -->


// formatting
= User Input =
println!("{:>4}", 2)            // "   2" right align
<blockquote>
println!("{:0>4}", 2)           // "0002"  right align, padded w/ zeros
<syntaxhighlight lang="rust">
println!("{var:>4}, var="boo") // " boo"  right align
let name = String::new();
io::stdin().read_line(&mut name);
</syntaxhighlight>
</syntaxhighlight>
</blockquote><!-- print -->
</blockquote><!-- input -->
 
= Files =
<blockquote>
 
</blockquote><!-- Files -->

Latest revision as of 08:34, 9 February 2023

Documentation

std::fs https://doc.rust-lang.org/std/fs/index.html

Stdin, Stdout, Stderr

Stdout/Stderr

println!("out");   // write to stdout
eprintln!("err");  // write to stderr

Stdin

NOTE:

rust nightly has a std::io::IsTerminal that checks if the stream is a pipe or a tty.
but besides this there is no builtin way to verify this.
you can do it manually with rust libc, but the most portable way is to use rust atty.

read from stdin

extern crate atty;
use std::io;
use std::io::BufRead;

/// read big files
fn buffered_read_all_stdin() {
    // don't read unless stdin is a pipe
    if atty::is(atty::Stream::Stdin) {
        return
    }
    let stdin = io::stdin();
    let handle = stdin.lock();
    let lines: Vec<String> = handle
        .lines()
        .map(|res| res.unwrap_or_default())
        .collect();
    print!("START\n{}\nFINISH\n", lines.join("\n"));
}

manual buffered read

extern crate atty;
use std::io::Read;
use std::str;

/// like `tail -f`
fn manually_buffered_read_stdin() {
    // don't read unless stdin is a pipe
    if atty::is(atty::Stream::Stdin) {
        return
    }

    let mut buffer: [u8; 1024] = [0; 1024];
    let stdin = io::stdin();
    let mut handle = stdin.lock();

    loop {
        let bytes_read = handle
            .read(&mut buffer[..])
            .unwrap_or(0);

        // reached EOF
        if bytes_read == 0 {
            break;
        }
        print!("{}", str::from_utf8(&buffer).unwrap());
    }
}

User Input

let name = String::new();
io::stdin().read_line(&mut name);

Files