Resetting a mutable string variable and getting an Err

So I'm trying to understand why I'm getting the following error. I was able to fix it by adding removing the comment from the line that's prefixed with "// REMOVE COMMENT TO FIX!"

use std::io;
use rand::prelude::*;

fn main() -> ()
{
    let mut input_s = String::new();
    println!("Enter number:");
    let _ = io::stdin().read_line(&mut input_s);
    let mut input_n: i32 = input_s.trim().parse().unwrap();
    let target_value: i32 = thread_rng().gen_range(0..101);
    loop
    {
        // REMOVING OPERATION CODE FOR BRIEVITY
        // REMOVE COMMENT TO FIX! let mut input_s = String::new();
        let _ = io::stdin().read_line(&mut input_s);
        input_n = input_s.trim().parse().unwrap();
    }
}

If I try to run the following code I get an error on the last line within the loop that says: "thread 'main' panicked at 'called 'Result::unwrap()' on an 'Err' value: ParseIntError { kind: InvalidDigit }'"

If I uncomment the aformentioned line, the code runs fine (no changes in input). I have a feeling this has something to do with me not be able to update the input_s variable, but I'm curious as to why that would be since the value is mutable and I passed a mutable reference when calling it.

Read's methods don't overwrite the buffer, they append to it; but this is clearly described in the docs. You probably want input_s.clear().

1 Like

Thanks for responding. Your solution definitely works, but with regards to "appending" I thought that at first and did an experiment and saw some odd behavior. I gave input 1 the first time and then 1 the second time in the loop and printed after the 2nd input, the result that was printed was "1", instead of "11" or "1\n1". Any thoughts?

To be clear about what I did.

use std::io;
use rand::prelude::*;

fn main() -> ()
{
    let mut input_s = String::new();
    println!("Enter number:");
    let _ = io::stdin().read_line(&mut input_s);  // gave the value "1"
    let mut input_n: i32 = input_s.trim().parse().unwrap();
    let target_value: i32 = thread_rng().gen_range(0..101);
    loop
    {
        // REMOVING OPERATION CODE FOR BRIEVITY
        // REMOVE COMMENT TO FIX! let mut input_s = String::new();
        let _ = io::stdin().read_line(&mut input_s);   // gave the value "1"
        println!("Val of input: {}", input_s")      // output was Val of input: 1
        input_n = input_s.trim().parse().unwrap();
    }
}

That's because you are declaring a new variable in every iteration. That's not the same as assigning to the variable declared outside the loop. Google "shadowing".

Use code blocks:

```
Code goes here
```

And read more here.

4 Likes

Will do, @quinedot
Thanks.

I wasn't declaring a new variable in every single iteration. Those variables were declared outside of the loop.
The clear call was definitely the best answer, thanks for that.
After doing a little more debugging the reason why my failure was happening with the "unwrap" call was because the '\n' character was still on the string from the previous sets of the string and it when appending with another number and the succeeding number/string value.

I was referring to this line:

This suggests to me that uncommenting this line is what fixed your immediate problem first, and this does declare the variable inside the loop body, i.e., recreates it upon every iteration.

I think we're just talking past each other. When I uncomment that line of code, the problem does fix and I don't have an issue (but the clear solution, IMHO is better).
In the response that we were discussing with the new declaration on every single iteration, I was referring to the append not happening as expected, but that was due to the '\n' character and the failure when calling unwrap().
No worries. Didn't matter much in the end, anyhow. Thanks for responding and the insight.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.