rust

How can I read one character from stdin without having to hit enter?


I want to run an executable that blocks on stdin and when a key is pressed that same character is printed immediately without Enter having to be pressed.

How can I read one character from stdin without having to hit Enter? I started with this example:

fn main() {
    println!("Type something!");

    let mut line = String::new();
    let input = std::io::stdin().read_line(&mut line).expect("Failed to read line");

    println!("{}", input);
}

I looked through the API and tried replacing read_line() with bytes(), but everything I try requires me to hit Enter before read occurs.

This question was asked for C/C++, but there seems to be no standard way to do it: Capture characters from standard input without waiting for enter to be pressed

It might not be doable in Rust considering it's not simple in C/C++.


Solution

  • Use one of the 'ncurses' libraries now available, for instance this one.

    Add the dependency in Cargo

    [dependencies]
    ncurses = "5.86.0"
    

    and include in main.rs:

    extern crate ncurses;
    use ncurses::*; // watch for globs
    

    Follow the examples in the library to initialize ncurses and wait for single character input like this:

    initscr();
    /* Print to the back buffer. */
    printw("Hello, world!");
    
    /* Update the screen. */
    refresh();
    
    /* Wait for a key press. */
    getch();
    
    /* Terminate ncurses. */
    endwin();