Common Standard Macros
print!
The print! macro writes formatted text to the standard output stream (stdout) without appending a trailing newline (\n).
Buffering Behavior and Explicit flush()
By default, standard output (io::stdout()) in Rust is line-buffered when connected to an interactive terminal: bytes buffered by print! are held in memory until a \n character is written, the internal buffer fills up, or io::stdout().flush() is called explicitly.
When displaying an interactive prompt (print!("Enter username: ");) or a single-line progress indicator before blocking on input or work, always call io::stdout().flush() so the text appears on screen immediately:
use std::io::{self, Write};
fn main() -> io::Result<()> {
print!("Loading modules: ");
io::stdout().flush()?; // Forces buffered prompt to appear immediately
for module in ["core", "net", "storage"] {
print!("[{module}] ");
io::stdout().flush()?;
}
println!("done.");
Ok(())
}
Loading modules: [core] [net] [storage] done.
Building Tables or Grids Row by Row with print! and println!
Combining print! for cells across a row with println!() at the end of each row formats 2D tables cleanly without allocating intermediate row strings:
fn main() {
for row in 1..=3 {
for col in 1..=4 {
print!("{:>4}", row * col);
}
println!(); // Terminates the current row
}
}
1 2 3 4
2 4 6 8
3 6 9 12
print! vs. println!
| Macro | Appends \n? |
Triggers Automatic Line-Buffer Flush? | Zero-Argument Call Allowed? |
|---|---|---|---|
print!("...") |
No | Only if format string contains \n |
No (print!("") is a no-op) |
println!("...") |
Yes | Yes (on interactive terminals) | Yes (println!() prints \n) |