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

后端 未结 3 1194
时光说笑
时光说笑 2020-12-01 14:13

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.

3条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-01 14:27

    You can also use termion, but you will have to enable the raw TTY mode which changes the behavior of stdout as well. See the example below (tested with Rust 1.34.0). Note that internally, it also wraps the termios UNIX API.

    Cargo.toml

    [dependencies]
    termion = "1.5.2"
    

    main.rs

    use std::io;
    use std::io::Write;
    use std::thread;
    use std::time;
    
    use termion;
    use termion::input::TermRead;
    use termion::raw::IntoRawMode;
    
    fn main() {
        // Set terminal to raw mode to allow reading stdin one key at a time
        let mut stdout = io::stdout().into_raw_mode().unwrap();
    
        // Use asynchronous stdin
        let mut stdin = termion::async_stdin().keys();
    
        loop {
            // Read input (if any)
            let input = stdin.next();
    
            // If a key was pressed
            if let Some(Ok(key)) = input {
                match key {
                    // Exit if 'q' is pressed
                    termion::event::Key::Char('q') => break,
                    // Else print the pressed key
                    _ => {
                        write!(
                            stdout,
                            "{}{}Key pressed: {:?}",
                            termion::clear::All,
                            termion::cursor::Goto(1, 1),
                            key
                        )
                        .unwrap();
    
                        stdout.lock().flush().unwrap();
                    }
                }
            }
            thread::sleep(time::Duration::from_millis(50));
        }
    }
    

提交回复
热议问题