Info
This post is auto-generated from RSS feed The Rust Programming Language Forum - Latest topics. Source: Idiomatically prompting for a single character response
As I've been experimenting with Rust by converting very simple C++ programs, I've struggled to come up with a simple idiomatic console prompt and get response pattern. This is something that the Rust book's chapter 2 addresses but in my opinion skimps over two aspects.
I don't want to get suggestions as given to a similar thread, like using the text_io
crate. Rather, I'm trying to understand why Rust requires what it does and verify that it does require the steps discussed below. I'm thinking perhaps it's because simple console prompt and input weren't needed or too crucial when Rust was being developed for a browser engine, compared to the origins of C or C++ in the days of hardware teletypes or VT100s, but maybe there are other explanations.
Anyway, here is the simple C++ example,
char ask_yes_no()
{
char response;
do {
cout << "Please enter 'y' or 'n': ";
cin >> response;
} while (response != 'y' && response != 'n')
return response;
}
And here's my attempt at translating that to Rust:
fn ask_yes_no() -> char {
let mut response: char;
loop {
print!("Please enter 'y' or 'n': ");
io::stdout().flush().unwrap();
let mut resp = String::new();
io::stdin().read_line(&mut resp).unwrap();
response = resp.trim().chars().next().unwrap();
if response == 'y' || response == 'n' {
break;
}
}
response
}
The first noticeable difference with the guessing game is that uses println!
whereas most console interfaces (that I've seen at least) leave the cursor after the prompt. Apparently however, in order to achieve that, it is necessary to flush stdout (in C or C++, the input statement automatically takes care of that). If you fail to do this, the user doesn't see any output. Is there some not obvious safety concern for this, or some other rationale?
The second inconvenience is that in order to get a single character (or number, text or whatever) one must first allocate (on the heap) an empty mutable string, then use read_line
and then various extra steps like trimming, parsing and so forth.
Of course, under the covers, C (with fgets()
) or C++ are doing some of that for the programmer, but they also provide very low level access if needed, even to write terminal drivers.
So is there some idiomatic, non-external crate approach to dealing with this, other than the obvious "create your own little function to prompt without println" and creating multiple other functions for dealing with different primitive types?
3 posts - 3 participants
🏷️ Rust_feed