Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

Rust: stdin().read_line() goes onto the next line automatically

Code in this thread will be formatted as C# because it's easier to read than having unhighlighted c ode, but it's all written in Rust, which is not available as a formatting option.
There's an issue I've been repeatedly running into with Rust when creating CLI applications, for example, the most familiar Guessing Game from the tutorial (although fairly modified to fit the scenario):

C#:
use std::io;
use rand::Rng;
use std::io::Write;
use std::cmp::Ordering;

fn main() {
    println!("[+] Guessing Game:");
    println!("[+] A random number will be selected between 0 to 100 (inclusive).");
    println!("[+] You'll be asked to enter numbers until you enter the correct number.");
    println!("[+] The game will support you by telling you which direction your next game should be.");
    println!();

    let target: u32 = rand::thread_rng().gen_range(0..=100);
    let mut guess_raw = String::new();

    loop {
        print!("[+] Enter your guess: ");
        io::stdout().flush().unwrap();

        guess_raw.clear();
        io::stdin().read_line(&mut guess_raw).expect("Failed to read line.");

        let guess: u32;
        match guess_raw.trim().parse() {
            Ok(parsed_number) => {
                guess = parsed_number;
            },
            Err(_error) => {
                print!(" [NOT A NUMBER]");
                io::stdout().flush().unwrap();
                continue;
            }
        }

        match guess.cmp(&target) {
            Ordering::Less => {
                print!(" [TOO SMALL]");
                io::stdout().flush().unwrap();
                continue;
            },
            Ordering::Greater => {
                print!(" [TOO BIG]");
                io::stdout().flush().unwrap();
                continue;
            },
            Ordering::Equal => {
                print!(" [CORRECT]");
                io::stdout().flush().unwrap();
                break;
            }
        }
    }

    println!();
    println!("[+] You've won the game!");
}

Well then, with this in mind, looking at the code gives you the thought it would look a bit like this:
Code:
[+] Guessing Game:
[+] A random number will be selected between 0 to 100 (inclusive).
[+] You'll be asked to enter numbers until you enter the correct number.
[+] The game will support you by telling you which direction your next game should be.

[+] Enter your guess: 10 [TOO SMALL]
[+] Enter your guess: 50 [TOO SMALL]
[+] Enter your guess: 80 [TOO SMALL]
[+] Enter your guess: 90 [TOO SMALL]
[+] Enter your guess: 95 [TOO SMALL]
[+] Enter your guess: 100 [TOO BIG]
[+] Enter your guess: 98 [TOO BIG]
[+] Enter your guess: 97 [CORRECT]
[+] You've won the game!

Process finished with exit code 0

But this is what it actually looks like:
Code:
[+] Guessing Game:
[+] A random number will be selected between 0 to 100 (inclusive).
[+] You'll be asked to enter numbers until you enter the correct number.
[+] The game will support you by telling you which direction your next game should be.

[+] Enter your guess: 50
 [TOO BIG][+] Enter your guess: 30
 [TOO SMALL][+] Enter your guess: 40
 [TOO SMALL][+] Enter your guess: 45
 [TOO SMALL][+] Enter your guess: 48
 [CORRECT]
[+] You've won the game!

Process finished with exit code 0


And after some research I've reached the conclusion that the issue is with the following line:
io::stdin().read_line(&mut guess_raw).expect("Failed to read line.");

Particularly, io::stsdin().read_line(), which calls the following (eventually):
unsafe { append_to_string(buf, |b| read_until(self, b'\n', b)) }

The above call is what I'm pretty sure is the cause for the entire issue, but I've yet to find any reasonable way to work around it. This problem came up a lot in places like Reddit but only in the sense that the result of the read included the newline character, in which case it can easily just be trimmed, but that doesn't allow you to write in-line after text has been read from stdin.
Does anyone have a clue on a way to read a line in Rust without having it skip to the next line?
 
I have no experience with Rust, so please, bear with me on this one.

Reading over what you've said others on Reddit have said, the function includes a newline character at the end of the input, which as we know, can easily be trimmed off. Do you know if Rust has a function in its standard library for trimming off characters? If not, is it like some lanaguges(e.g. Java) where it has one output function with a newline, one output function without a newline, etc. etc.? Possibly looking through a Rust reference manual on input functions might help with this.

I don't have time right now to do so, but will when I get the chance. This is an interesting problem that is so simple.
 
Reading over what you've said others on Reddit have said, the function includes a newline character at the end of the input, which as we know, can easily be trimmed off
Aye, what he means is that when you do read_line() into the buffer, the buffer includes the newline character at the end which can then be trimmed off via trim(), but it gets outputted at the end of read_line() regardless of any consequent output.
 
Aye, what he means is that when you do read_line() into the buffer, the buffer includes the newline character at the end which can then be trimmed off via trim(), but it gets outputted at the end of read_line() regardless of any consequent output.
Hmm...If the trim function does not work, then surely there must be a function that does not include this character. I'm reading through all of these right now, and I absolutely hate it.

Please let me know if you find anything of use in that link.
 

Buy us a coffee!

Back
Top Bottom