---
title: "1.5 Introduction to println! and formatting"
description: "Printing in Rust: println! versus print!, placeholder syntax, named and positional arguments, and escape sequences."
url: "https://learnrust.net/chapter-1/println-and-formatting/"
last_updated: "2026-06-11"
---

# 1.5 Introduction to println! and formatting

You've been using `println!` since your first program. This lesson makes you fluent in it, which is worth doing early: printing is how your programs will talk to you for the entire course, including when you're hunting bugs (chapter 3 turns it into a debugging technique).

## println! and print!

`println!` writes its text to the screen and then ends the line, so the next print starts on a fresh one. Its sibling `print!` writes the text and *stays put*:

```rust
fn main() {
    print!("One. ");
    print!("Two. ");
    println!("Three.");
    println!("Four.");
}
```

```
One. Two. Three.
Four.
```

The three pieces printed with `print!` and `println!` ended up on one line; only `println!` moved on. Most of the time `println!` is what you want, with one wrinkle worth knowing now: terminals are allowed to hold back an unfinished line, so text from a bare `print!` may not appear on screen until something ends the line. We'll dodge that wrinkle in the next lesson and dissolve it properly in chapter 20.

## Placeholders

To mix values into the text, use `{}` as a placeholder, then supply the values as extra arguments, in order:

```rust
fn main() {
    let a = 6;
    let b = 4;
    println!("{} plus {} is {}", a, b, a + b);
}
```

```
6 plus 4 is 10
```

Each `{}` is filled by the next argument. And note the third argument: `a + b` is a calculation, not a variable. Any expression that produces a printable value works as an argument; the math happens first, then the result is printed.

When the value you're printing is a single variable, there's a shortcut you've already been using: put the name right inside the braces.

```rust
fn main() {
    let score = 250;
    println!("score: {score}");
}
```

```
score: 250
```

The inline form only accepts a plain variable name. `{a + b}` doesn't compile; calculations have to go the `{}`-plus-argument route. A good habit that keeps both rules easy to remember: braces hold a *name* or nothing.

> **Best practice**
>
> Prefer the inline form (`{score}`) when printing a variable: the text reads like the output it produces, and there's no counting-arguments gymnastics. Use empty `{}` with arguments when printing computed values.

Two more placeholder tricks complete the set. Placeholders can be numbered to reuse or reorder arguments (`{0}` is the first argument, `{1}` the second):

```rust
fn main() {
    println!("{0}, {1}! {0}!", "Go", "team");
}
```

```
Go, team! Go!
```

And arguments can be given names, which read nicely when there are several:

```rust
fn main() {
    println!("{name} scored {points} points", name = "Ada", points = 250);
}
```

```
Ada scored 250 points
```

You'll see all three styles in real code; inline names dominate modern Rust.

## Escape sequences

Some characters can't be typed into a string literally, so they're written as **escape sequences**: a backslash plus a code. The ones you'll actually use:

- `\n` starts a new line ("newline"). `println!` effectively adds one of these for you at the end; `print!` doesn't.
- `\t` inserts a tab, handy for rough columns.
- `\"` puts a double quote *inside* a double-quoted string.
- `\\` prints an actual backslash, since a lone one would start an escape.

And one non-backslash escape, because braces have a job now: to print a literal `{` or `}`, double it (`{{` and `}}`).

```rust
fn main() {
    println!("line one\nline two");
    println!("name:\tAda");
    println!("she said \"hello\"");
    println!("C:\\projects");
    println!("braces look like {{}}");
}
```

```
line one
line two
name:	Ada
she said "hello"
C:\projects
braces look like {}
```

A `\n` in the middle of a string is also a tidy way to print two lines with one statement, which you'll see in examples from here on.

## Quiz time

**Question #1**

What does this program print?

```rust
fn main() {
    print!("a");
    println!("b\nc");
    println!("d");
}
```

<details class="solution">
<summary>Show solution</summary>

```
ab
c
d
```

The `print!` leaves the cursor after `a`, so `b` lands on the same line; the `\n` ends that line and starts the one holding `c`; the `println!` ends it; `d` gets its own line.

</details>

**Question #2**

What does this program print?

```rust
fn main() {
    let x = 3;
    println!("{0} times {1} is {2}, and {1} times {0} is also {2}", x, 5, x * 5);
}
```

<details class="solution">
<summary>Show solution</summary>

```
3 times 5 is 15, and 5 times 3 is also 15
```

`{0}` is `x` (3), `{1}` is 5, and `{2}` is the computed `x * 5`. Numbered placeholders can repeat and reorder freely.

</details>

**Question #3**

Predict the compiler error: what's wrong here?

```rust
fn main() {
    println!("the answer is {}");
}
```

<details class="solution">
<summary>Show solution</summary>

The format string has one `{}` placeholder but no argument to fill it, and the program doesn't compile. The compiler says exactly that: "1 positional argument in format string, but no arguments were given", pointing at the braces. (This check happening at compile time is quietly remarkable; in C, the equivalent mistake compiles and misbehaves at runtime.)

</details>

You can now talk *to* the user. Next lesson, the conversation goes both ways: reading what they type back.

## Sitemap

See the full [sitemap](https://learnrust.net/sitemap.md) for all pages.
