Conversion failure

use std::io;

fn main() {

 
 	println!("please enter number of students");

 	let mut stude = "some_string".to_string();	
 	
 	io::stdin().read_line(&mut stude).expect("Failed to read input");

 	let stude = stude.trim().parse().expect("conversion failure");

 	//let stude = stude as usize ; 
 	let mut input :String = String::new();
 	let mut j : Vec<String> = Vec::new();

 	for some_int in 0..stude {
 		println!("\n#{} = ",some_int);
 		io::stdin().read_line(&mut input).expect("Failed to read input");
            j.push(input);
 	}

 	for some_string in j.iter() {
 		println!("{}",some_string);
 	}
}

here is the error exception :

C:\Users\Dell\rust\io>cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.03s
     Running `target\debug\io.exe`
please enter number of students
4
thread 'main' panicked at 'conversion failure: ParseIntError { kind: InvalidDigit }', 
libcore\result.rs:945:5
note: Run with `RUST_BACKTRACE=1` for a backtrace.
error: process didn't exit successfully: `target\debug\io.exe` (exit code: 101)

Hi,

please make sure to post the actual code that exhibits the problem. The main function you posted up there does not compile for reasons that have nothing to do with the problem.

The issue you have is that you are trying to parse some_string4. read_line does not clear the input buffer, but instead append to it.

Try:


 	let mut stude = "".to_string();	
 	
 	io::stdin().read_line(&mut stude).expect("Failed to read input");

 	let stude = stude.trim().parse().expect("conversion failure");

dude its does compile , thats why i have coversion failure

is there any function to clear buffer for reading ?

also when i declare variable outside loop , it says value moved

let mut input :String = String::new();

even though i pass &mut refference

No, it doesn't.

The loop is not interesting, it happens in the first lines before the loop.

1 Like

so redeclaring it in loop every time is wise ?

No, what I'm saying is that you should work from the top down, ignoring the loop for a while (maybe even comment it out) and fix the code before it first.

1 Like

Hi Madara,

I remeber, that we talked a lot in a different post and I can see, that you make the same "mistakes" again (not as much, but you do).

Don't specify the type, unless absolutly necessary, there is no need in doing so. Because of String::new() rust knows, that the result is a String.
Also, I really don't like mut variables as such. There is no way, that you can avoid the mut string, but the mut vec.
Write this as such:

let j = (0..stude).map(|idx| {
    let mut input = String::new();
    println!("\n#{} = ", idx);
    io::stdin().read_line(&mut input).expect("Failed to read input");
    input
}).collect::<Vec<_>>();
1 Like

I prefer to declare datatype explicitly as a matter of habit and Rust allows that habit.
that

.map(|some_var|{some_process})

thing is not much clear to me (clear to some degree)(i haven't encountered it in the book yet )
and it's just my 3rd month with rust

but thanks for the code, ill take a look into it

"I prefer to clap into my hands, before brushing my teeths." Sure, you can do that, but you can leave that out, it makes no difference :wink:

Jokes aside. rust allows you to program in a functional way. Functional programming has the advantage, that it allows you to program side-effect free (it does not alter its environment). For example.

assert_eq!(21, vec![1, 2, 3, 4, 5, 6].iter().fold(0, |s, e| s + e));

vs

let mut res = 0;
for i in &vec![1, 2, 3, 4, 5, 6] {
    res = res + i;
}
assert_eq!(21, res);

You see, there are no "external variables" involved and it is even shorter, but for the same performance!

For the code I gave you is is mostly the same. I iterate over the range from 0 to stude and do with every number (now called idx) the same as you did in your for loop. In the end I will return input which then will be hold as an value, which can be used later. In my case I just collect the example into a vec. It is necessary to give the type Vec here, but not the inner type. The reason for this is, that you can collect into many types, like Vec, Option, String, Result (am I missing something).

The really cool part is, that you can chain these operations!

(0u8..255) // iterate from 0 to 255 (exclusive)
    .filter(|x| x.is_ascii()) // check if that integer is in ascii range
    .map(|x| x as char) // convert it to an character (note, that you now converted your u8 to  a char!!! Amazing!)
    .skip_while(|&x| x < 'a') // skip all the values while they are lower than 'a'
    .take_while(|&x| x <= 'z') // take all the values as long as they are lower equal than 'z'
    .collect::<String>() // collect them into a string
// abcdefghijklmnopqrstuvwxyz

All this is done without any external variable, just pure iteration magic.

You find the docs for map/Map and fold.

to get more understanding of rust , i have started making own DB
just for sake of gaining better understanding

and mate , you have spent quite a time with rust with those are amazing examples