Module 2 · Core Syntax & Types ⏱ 19 min

Formatting Output (printf, format specifiers)

By the end of this lesson you will be able to:
  • Use System.out.printf with %d, %f, %s, and %n
  • Control width and precision in format specifiers
  • Predict the exact string produced by a format call

System.out.println is fine for simple text, but printf gives you control. You write a format string with placeholders — called format specifiers — and provide the values to fill them. The result is precise, readable output without messy string concatenation.

Mastering printf is worth the effort because real programs print tables, prices, percentages, and aligned reports. A price printed as 2.5 looks amateur; the same price printed as $ 2.50 looks professional. The difference is one format string. The printf tradition comes from C, and nearly every mainstream language borrows the same syntax, so learning it once pays off everywhere.

Common specifiers

Every specifier starts with % and ends with a conversion character:

  • %s — string
  • %d — decimal integer
  • %f — floating-point number
  • %n — platform-independent newline

You can add modifiers between the % and the letter: %.2f rounds to two decimal places; %10s right-aligns in a field ten characters wide; %-10s left-aligns. The format string and arguments must match in type — %d with a String is a compile-time or runtime error.

flowchart LR
  F["Format string"] --> S["%s · string"]
  F --> D["%d · integer"]
  F --> N["%f · floating-point"]
  F --> W["%10s · width 10"]
  F --> P["%.2f · precision 2"]
  style F fill:#c2410c,color:#fff
Common printf specifiers and their effects.
Main.java — printf with strings, integers, width, and precision. Real, compiling Java.
public class Main {
    public static void main(String[] args) {
        int age = 7;
        double price = 2.5;
        String item = "Apple";

        System.out.printf("%s: %d years%n", item, age);
        System.out.printf("Price: $%.2f%n", price);
        System.out.printf("[%10s]%n", item);
        System.out.printf("[%-10s]%n", item);
    }
}

Width and alignment

Width controls how much space a value occupies. %10s pads a short string with leading spaces so the result is exactly ten characters wide; %-10s pads on the right instead. This is how you build columns that line up neatly.

Positive width right-aligns; the - flag left-aligns. The value is never truncated — if you ask for %3s and hand it "Apple", you still get all five letters. Width is a minimum, not a maximum. For numbers, a leading zero flag (%08d) pads with zeros instead of spaces, which is common for IDs and timestamps.

flowchart LR
  A["Apple"] -->|"%10s"| B["     Apple"]
  A -->|"%-10s"| C["Apple     "]
  A -->|"%3s"| D["Apple"]
  style A fill:#c2410c,color:#fff
Width and alignment control how a value sits inside its field. Width is a minimum, not a maximum.
Main.java — width, alignment, and zero-padding in action.
public class Main {
    public static void main(String[] args) {
        String item = "Apple";
        int order = 42;

        System.out.printf("[%10s]%n", item);
        System.out.printf("[%-10s]%n", item);
        System.out.printf("[%08d]%n", order);
    }
}

Precision

For floating-point numbers, precision sets how many digits appear after the decimal point. %.2f always shows two places, rounding if necessary. %.1f shows one place. Without a precision, %f defaults to six decimal places — which is usually far more than you want.

Precision also works for strings: %.3s prints only the first three characters. This is useful when you need to fit long text into a fixed-width column. Rounding follows the usual rules: 2.55 with %.1f becomes 2.6 because the second decimal digit is 5 or higher.

Main.java — precision on floating-point numbers and strings.
public class Main {
    public static void main(String[] args) {
        double pi = 3.14159;

        System.out.printf("%.1f%n", pi);
        System.out.printf("%.2f%n", pi);
        System.out.printf("%.4f%n", pi);
        System.out.printf("%.3s%n", "Hello");
    }
}

Combining width and precision

You can use both modifiers together: %8.2f means 'a floating-point number, eight characters wide, with two digits after the decimal point'. The width includes the decimal point and the digits after it. If the number is narrower than the width, spaces pad it on the left; if it is wider, the full number is still printed. This combination is what makes tabular reports look professional.

Experiment with the order: width comes first, then a dot, then precision. %10.3s gives you a string field ten characters wide, but only the first three letters of the value are shown. Reversing the numbers changes the meaning entirely, so read the specifier carefully before you run the program.

Escaping % and argument order

If you want a literal percent sign in the output, write %% in the format string. A single % followed by an unknown letter is an error.

The arguments after the format string are matched in order: the first % consumes the first argument, the second % consumes the second, and so on. If you provide too few arguments, the call throws an exception at runtime. If you provide too many, the extras are silently ignored. Keeping the count straight is easiest when the format string and argument list sit on the same screen.

flowchart LR
  F["Format string"] --> M1["%s → arg 1"]
  F --> M2["%d → arg 2"]
  F --> M3["%.2f → arg 3"]
  F --> N["%n → newline"]
  style F fill:#c2410c,color:#fff
Arguments are consumed in order, left to right, one per specifier.
Exercise

What does this program print? Read it carefully and type the exact output (four lines).

public class Main {
    public static void main(String[] args) {
        int age = 7;
        double price = 2.5;
        String item = "Apple";

        System.out.printf("%s: %d years%n", item, age);
        System.out.printf("Price: $%.2f%n", price);
        System.out.printf("[%10s]%n", item);
        System.out.printf("[%-10s]%n", item);
    }
}
Exercise

Which format specifier prints an integer value?

Exercise

What does this program print? Read it carefully and type the exact output (two lines).

public class Main {
    public static void main(String[] args) {
        double score = 87.555;
        System.out.printf("%.1f%n", score);
        System.out.printf("[%8.2f]%n", score);
    }
}
Exercise

What does this program print? Read it carefully and type the exact output (one line).

public class Main {
    public static void main(String[] args) {
        String name = "Ada";
        int rank = 1;
        double score = 99.5;
        System.out.printf("%-5s %d %.1f%n", name, rank, score);
    }
}
Exercise

What happens when you run System.out.printf("%d", 3.5);?

Recap

  • printf uses a format string with % specifiers matched to arguments in order.
  • %s is for strings, %d for integers, %f for floating-point, and %n for a platform-independent newline.
  • Width (%10s) controls minimum field size; - (%-10s) left-aligns.
  • Precision (%.2f) rounds floating-point output; for strings it limits length.
  • Match specifiers to argument types. A mismatch may compile but crash at runtime.

Next you will meet ternary and compound-assignment operators — compact ways to express decisions and updates in a single line.

Checkpoint quiz

What does System.out.printf("%.1f", 2.55); print?

What does %n do in a printf format string?

Go deeper — technical resources