0

I am just starting to learn Rust and I am trying to create a guessing game. However, I keep running into an error where reading from the stdin captures all previous inputs to stdin as well. I am running this on Windows 10.

My actual guessing game program thing:

use std::{io};

use rand::Rng;

fn main() {
    let mut rng = rand::thread_rng();
    let x: u8 = rng.gen_range(0..=10);

    let mut end_game: bool = false;

    println!("Welcome to the number guessing game");
    println!("After each guess, I'll let you know if you're too high or too low");

    let mut guess: String = String::new();
    let mut guess_int: u8;
    while !end_game {
        println!("Guess: ");
        io::stdin().read_line(&mut guess).expect("Failed to read input");
        println!("You guessed {guess}");

        guess_int = guess.trim().parse().unwrap();

        if guess_int == x {
            end_game = true;
        } else if guess_int > x {
            println!("{} is too high!", guess_int);
        } else if guess_int < x {
            println!("{} is too low", guess_int);
        }
    }

    println!("You got it!");

}

And then here is another rust file that I wrote to just make sure the problem I assumed was happening is happening.

use std::io;

fn main() {
    let mut input: String = String::new();

    println!("what is your name?");
    io::stdin().read_line(&mut input).expect("!!");

    println!("Input1: {input}");

    println!("age?");
    io::stdin().read_line(&mut input).expect("!!");

    println!("Input2: {input}");
}

Which gave me this out:

what is your name?
Input1: Joe

age?
420
Input2: Jack
420


Is there a way to flush the stdin or anything like that? Thanks in advance.

3
  • 3
    read_line(&mut input) appends to the String. You probably need to .empty() the string after each input. Commented Jul 28, 2022 at 17:51
  • 2
    The correct method is clear rather than empty, but that aside you're exactly correct. Also visible, documented but commonly tripping people, read_line will also append the EOL to the buffer. Commented Jul 28, 2022 at 18:11
  • Does this answer your question? How to overwrite mutable string inside a loop? Commented Jul 29, 2022 at 8:01

1 Answer 1

1

Thanks to both @PitaJ and @Masklinn, both of whom supplied answers.

The issue is that std::io::stdin().read_line(...) appends to the String passed by reference to the function. As such, one must empty the String you pass in before reusing it to get input. This can be done with either String::new() or StringNameHere.clear().

My working code ended up looking like this:

use std::{io};

use rand::Rng;

fn main() {
    // println!("Hello, world! : ");

    let mut rng = rand::thread_rng();
    let x: u8 = rng.gen_range(0..=20);
    let mut num_guesses: u8 = 0;

    let mut end_game: bool = false;

    println!("Welcome to the number guessing game");
    println!("After each guess, I'll let you know if you're too high or too low");

    let mut guess: String = String::new();
    let mut guess_int: u8;
    while !end_game {
        println!("Guess: ");
        io::stdin().read_line(&mut guess).expect("Failed to read input");

        guess_int = guess.trim().parse().unwrap();
        guess.clear();  //guess = String::new() works too, but I think this method is easier to understand
        num_guesses += 1;

        if guess_int == x {
            end_game = true;
        } else if guess_int > x {
            println!("{} is too high!", guess_int);
        } else if guess_int < x {
            println!("{} is too low", guess_int);
        }
    }

    println!("You got it! You guessed the magic number ({}) in {} guesses", x, num_guesses);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.