stringrust

Rust println! result is different that print! when using time::sleep


Ok, so I haven't worked with Rust for that long so sorry if this is dumb. But I'm trying to make a print function that takes in a string and then prints the string character by character on the same line and has a pause between each character. Here's the function:

fn talk(input: String){
    let inputVec: Vec<char> = input.chars().collect();
    
    let mut i = 0;
    loop{
        thread::sleep(time::Duration::from_millis(100));
        if i >= inputVec.len() {
            break;
        }
        print!("{}", inputVec[i]);
        i = i + 1;
    }
}

When I do this code with the print! macro, it doesn't work and just waits 100 milliseconds before printing the string as one print! call. But if I use println! then it works perfectly minus the new line for every character. Can someone help me with this or at least tell me why it doesn't work?


Solution

  • Like the comments of Vivick and drewtato, you need use flush of Write io's module Trait.

    use std::{thread, time};
    use std::io::{self, Write};
    
    fn main() {
        talk("Hello, world!\n".to_string());
    }
    
    fn talk (input: String) {
        let chars = Vec::<u8>::from(input);
        let mut i = 0;
        while i < chars.len() {
            print!("{}", chars[i] as char);
            io::stdout().flush().unwrap();
            thread::sleep(time::Duration::from_millis(100));
            i+=1;
        }
    }
    

    This works for me!

    But, the most simple way to do this is use eprint! macro, like this:

    use std::{thread, time};
    
    fn main() {
        talk("Hello, world!\n".to_string());
    }
    
    fn talk (input: String) {
        let chars = Vec::<u8>::from(input);
        let mut i = 0;
        while i < chars.len() {
            eprint!("{}", chars[i] as char);
            thread::sleep(time::Duration::from_millis(100));
            i+=1;
        }
    }
    

    and the documentation says:

    Use eprint! only for error and progress messages. Use print! instead for the primary output of your program.