Reputation: 77
Vec<&str>
.Vec[0]
and Vec[1]
to num1
and num2
.try_again
function.try_again
function with "Success" msg
(the main
function is there only for context,
the problem is in try_again
function)
use std::io::{self, Write, Read, Error, ErrorKind};
const ERR_MSG_STDIN_READ: &str = "Problem with getting input";
const ERR_MSG_STDOUT_FLUSH: &str = "Problem with flushing stdout";
fn main() {
loop {
clear_terminal();
print!("Write 2 ints separated by space: ");
let mut nums_string = String::new();
io::stdout().flush().expect(ERR_MSG_STDOUT_FLUSH);
io::stdin().read_line(&mut nums_string).expect(ERR_MSG_STDIN_READ);
let nums_str_vec: Vec<&str> = nums_string.trim()
.split(' ').collect();
let num1: i32 = match nums_str_vec[0].parse() {
Ok(num) => num,
Err(_) => match try_again("Error") {
true => continue,
false => break
}
};
let num2: i32 = match nums_str_vec[1].parse() {
Ok(num) => num,
Err(_) => match try_again("Error") {
true => continue,
false => break
}
};
print!("Write one of these[+,-,*,/] maths operation for 2 inputed ints: ");
let mut operation_string = String::new();
io::stdout().flush().expect(ERR_MSG_STDOUT_FLUSH);
io::stdin().read_line(&mut operation_string).expect(ERR_MSG_STDIN_READ);
let operation = match operation_string.trim().parse() {
Ok(char) => char,
Err(_) => match try_again("Error") {
true => continue,
false => break
}
};
match operation {
'+' => println!("{} {} {} = {}", num1, operation, num2, num1 + num2),
'-' => println!("{} {} {} = {}", num1, operation, num2, num1 - num2),
'*' => println!("{} {} {} = {}", num1, operation, num2, num1 * num2),
'/' => println!("{} {} {} = {} ({})", num1, operation, num2, num1 / num2, num1 % num2),
_ => match try_again("Error") {
true => continue,
false => break
}
}
io::stdin().read(&mut [0]).expect(ERR_MSG_STDIN_READ);
match try_again("Success") {
true => continue,
false => break
}
}
}
fn clear_terminal() {
print!("{}c", 27 as char);
io::stdout().flush().expect(ERR_MSG_STDOUT_FLUSH);
}
try_again
function shoud do?msg
to msg_new
for later changing.true
if 'n' return false
.msg
)main
function) match returned result of try_again
function => true means continue main loop, false means break the loop and end the program.fn try_again(msg: &str) -> bool {
let mut msg_new = msg;
loop {
println!("The calculation end up with {}.", msg_new);
print!("Do you want to make antoher calculation? (y/n): ");
let mut answer_string = String::new();
stdout().flush().expect(ERR_MSG_STDOUT_FLUSH);
stdin().read_line(&mut answer_string).expect(ERR_MSG_STDIN_READ);
match answer_string.trim().chars().next() {
Some('y') => true,
Some('n') => false,
_ => {
msg_new = "Error";
continue
}
};
}
}
step 7 (maybe we can say 6 and 7) the problem is in try_again
function.
try_again
functionWhen the program run try_again("Success");
:
stdin().read_line(&mut next_string)
doesn´t wait for users input and immediately go to _ =>
arm.msg
)msg
.Why the stdin().read_line(&mut next_string)
wait for input in secodn round of loop? How to solve it? Thanks for every answer!
I am totally new to rust, please explain everything what you write. OS: Windows 10, terminal: cmd (Command Promt)
Upvotes: 1
Views: 595
Reputation: 3718
You must check whether a 'y'
or a 'n'
was entered at all, e.g. with a guard:
fn next(msg: &str) -> bool {
let msg_new = msg;
loop {
clear_terminal();
println!("The calculation end up with {}.", msg_new);
print!("Do you want to make antoher calculation? (y/n): ");
let mut next_string = String::new();
stdout().flush().expect(ERR_MSG_STDOUT_FLUSH);
match std::io::stdin().read_line(&mut next_string) {
Ok(n) if n > 0 && next_string.chars().next().unwrap() == 'y' => break true,
Ok(n) if n > 0 && next_string.chars().next().unwrap() == 'n' => break false,
Ok(_) => {}, // other input is ignored
Err(err) => panic_any(err),
};
}
}
Btw: next
should be reserved for iterators
Upvotes: 1