Unexpected behavior of print! vs println!


#1

In the following code, I want to print out a line asking for number input.
If I use println!

fn main() {

  println!("Enter number value: ");

The line will be printed with a linefeed, so the number will be entered on the line underneath it.
As in my C++ code, I want the number to show in the terminal next to the statement.
But when I use print!, the statement isn’t displayed and the cursor goes to a blank 2nd line to wait for input.

fn main() {

  print!("Enter number value: ");

What do I need to do to display the message and have the cursor wait after the message on the same line for input?


#2

Here is the full input code.

fn main() {
  println!("Enter number value: ");

  let mut input = String::new();
  io::stdin().read_line(&mut input).ok().expect("failed to read line");
  let val: u64 = input.trim().parse().expect("Please type a number!");

#3

You’ll need to flush stdout: io::stdout().flush().unwrap().


#4

Thanks, here’s the full code to use flush(), to help others.

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

fn main() {
   print!("Enter number value: ");

    io::stdout().flush().unwrap();
    let mut input = String::new();
    io::stdin().read_line(&mut input).ok().expect("failed to read line");
    let val: u64 = input.trim().parse().expect("Please type a number!");

It would be nice if the developers would wrap this up in a macro and create something like cin << in C++.

This is way to many lines of code to repeatedly have to do for such a standard programming function. Show inputting as much love as outputting with print|ln!. :slight_smile:


#5

Also, please add this specific example on how to do number input into the online Rust Book.
It was very frustrating to have to search to find out how to do this simple task.


#6

This is what scan-rules (examples) is for.

Edit: not to imply that it’s an official position or anything; this sort of thing is just why I wrote it, is all.


#7

I think that @DanielKeep has invented a very rusty way of doing input with scan-rules, something the standard library simply doesn’t include by itself. What do you think @jzakiya, is scan-rules understandable for a newcomer to Rust?

Don’t you think that this kind of interactive input is a task that’s predominantly common when learning programming, in particular in older books? I doesn’t have that much connection to real world tasks… maybe that’s a boring perspective, but I think it’s part of the reason why it’s not prioritized in Rust.


#8

I would like to note that this behavior is explained in print!'s docs.

··· On Mar 17, 2016, 14:17 -0400, bluss, wrote: > bluss(https://users.rust-lang.org/users/bluss) > March 17 > > I think that@DanielKeep(https://users.rust-lang.org/users/danielkeep)has invented a very rusty way of doing input with scan-rules, something the standard library simply doesn't include by itself. What do you think@jzakiya(https://users.rust-lang.org/users/jzakiya), is scan-rules understandable for a newcomer to Rust? > > > Don't you think that this kind of interactive input is a task that's predominantly common when learning programming, in particular in older books? I doesn't have that much connection to real world tasks.. maybe that's a boring perspective, but I think it's part of the reason why it's not prioritized in Rust. > > > > > > > Visit Topic(https://users.rust-lang.org/t/unexpected-behavior-of-print-vs-println/5019/7)or reply to this email to respond > > > > To stop receiving notifications for this particular topic,click here(https://users.rust-lang.org/t/unexpected-behavior-of-print-vs-println/5019/unsubscribe). To unsubscribe from these emails, change youruser preferences(https://users.rust-lang.org/my/preferences) > > > > >

#9

Here is the equivalent C++ code I was trying to reproduce in Rust:

main()
{
  cout << "Enter number value: ";
  uint64 val;                      // find primes <= val (7..2^64-1)
  cin >> val;

I cannot image there is any technical reason Rust can’t create a macro to do the equivalent thing, which will work for 99% of most people’s needs.

Rust is scary enough for people coming from languages like Ruby (like me), Python, Javascript, etc which all have these common conscructs built. Why make it unnecessarily unfriendly!

The current Gold Standard system languages are C/C++ (Linux kernel, GIT, etc). For marketing, political, and social, et al reasons, the more you can do to provide out-of-the-box comparable functionality the better you will be at attracting the widest possible audience.

History has repeatedly shown (in so many cases) it’s not the best technology that invariably wins (Betamax vs VHS) it’s the easiest to use and/or cheapest that wins (IBM PC vs Mac).

Please, don’t let rigid philosophical ideology of how you think things should be done hamper your willingness to make the language as drop-dead easy to use as possible.


#10

It should be emphasized that the unexpected behavior of print! is the result of the behavior of the UNIX console, nothing in Rust.

The reason Rust’s standard library doesn’t have very expressive support for writing interactive UNIX command line programs is that Rust is a very young language with a very small standard library. As things evolve, other crates will be developed which will provide expressive APIs for interacting with the command line. Possibly some day one of these solutions will be integrated into the standard library.

This is nothing to do with being dogmatic, unfriendly, or rigid, but with the stage of the language’s development. Analogously, there was once a time when C++ did not have cout << and cin >>.


#11

File buffering is a well-known trap for newbies in a wide variety of languages. This discussion from Mark-Jason Dominus (using Perl, but that’s just a syntax thing) is a good classic.

Some languages, including C++ and Perl, automatically flush standard output on reads from standard input when a terminal is detected. This helps with simple examples like the one you posted, but leads to more confusing failures later in the learning curve; it might be good for a pre-RFC (I have no opinion on whether Rust should do this at this time).