Format Specifiers

Naveen AnamaneniUpdated · 5 min read

A printed bill has its prices lined up on the right, always with two decimal places, and item names lined up on the left. You can't get that by joining strings with +. Format specifiers are short codes such as %d and %.2f that tell printf exactly how to show each value: as what type, how wide, and with how many decimals.

The Parts of a Specifier

% flags width .precision conversion

%[flags][width][.precision]conversion. Only the % and the conversion letter are required.

ConversionForExampleResult
%dWhole numbers (int, long)printf("%d", 42)42
%fDecimals (double, float)printf("%f", 3.14159)3.141590
%sText, or anything elseprintf("%s", "Pune")Pune
%cA charprintf("%c", 'A')A
%bA booleanprintf("%b", true)true
%eScientific notationprintf("%e", 1234.5)1.234500e+03
%xHexadecimalprintf("%x", 255)ff
%nNew line (no value)printf("Hi%n")Hi and a new line
%%A literal % signprintf("18%%")18%

Width, Precision and Flags

Widths.java▶ Try it
public class Widths {
    public static void main(String[] args) {
        System.out.printf("[%d] [%5d] [%-5d] [%05d]%n", 42, 42, 42, 42);
        System.out.printf("[%.2f] [%8.2f]%n", 3.14159, 3.14159);
        System.out.printf("[%10s] [%-10s]%n", "Pune", "Pune");
        System.out.printf("[%,d] [%,.2f]%n", 1234567, 1234567.891);
    }
}
Output
[42] [   42] [42   ] [00042]
[3.14] [    3.14]
[      Pune] [Pune      ]
[1,234,567] [1,234,567.89]

How it works

  1. Width 5 makes the value take at least 5 characters. Numbers are right-aligned by default: [ 42].
  2. The - flag left-aligns: [42 ]. The 0 flag pads with zeros: [00042].
  3. Precision .2 means two decimal places: 3.14. With width 8, the result is padded to 8 characters.
  4. The , flag adds grouping separators: 1,234,567.

The square brackets aren't part of the format; they're there so you can see the spaces.

Try it yourself: change line 4 to use %.0f and %.4f. What does each print?

A Neat Bill

Width and precision together line up a table:

Bill.java▶ Try it
public class Bill {
    public static void main(String[] args) {
        String[] items = {"Rice 5 kg", "Toor dal", "Oil 1 L"};
        double[] prices = {340.0, 165.5, 189.75};
        double total = 0;
        for (int i = 0; i < items.length; i++) {
            System.out.printf("%-12s Rs. %8.2f%n", items[i], prices[i]);
            total += prices[i];
        }
        System.out.printf("%-12s Rs. %8.2f%n", "Total", total);
    }
}
Output
Rice 5 kg    Rs.   340.00
Toor dal     Rs.   165.50
Oil 1 L      Rs.   189.75
Total        Rs.   695.25

%-12s gives every name 12 characters, left-aligned, and %8.2f gives every price 8 characters with 2 decimals, right-aligned, so the decimal points line up. The loop is covered in "Java for Loop".

Rounding and Number Grouping

  • %.2f rounds half up: 2.345 prints as 2.35, and %.0f turns 2.5 into 3.
  • The , flag always groups in threes: 10,000,000. Java's built-in formatters don't produce Indian lakh and crore grouping (1,00,00,000), even with an Indian locale. You'd need a library such as ICU4J for that.
  • Grouping and decimal symbols follow the computer's locale. In Germany, %,.2f gives 1.234.567,89. Pass a locale to get the same result everywhere: String.format(Locale.US, "%,.2f", x).

When a Specifier Is Wrong

The compiler doesn't check format strings, so mistakes appear at runtime:

Terminal output
Exception in thread "main" java.util.IllegalFormatConversionException: d != java.lang.Double

That's %d given 5.5: %d needs a whole number. Too few values gives MissingFormatArgumentException. Too many values isn't an error; the extras are ignored.

Common Mistakes

Using %d for a double. Use %f (or %.2f). For a whole number from a double, cast it first: (int) price.

Forgetting %n. Without it, the next output continues on the same line.

Writing % alone for a percent sign. printf("18%") fails; write 18%%.

Practice

  1. Easy: Print Pi is about 3.14 using Math.PI and %.2f.
  2. Harder: Print a three-row marks table with the subject name left-aligned in 10 characters and the marks right-aligned in 5, then the percentage with one decimal place.

Quick check: Format specifiers

4 questions
1Which specifier prints a double with exactly two decimal places?
2What does printf("[%5d]", 42) print?
3What happens with printf("%d", 5.5)?
4How do you print a literal percent sign with printf?

Key Takeaways

Was this tutorial helpful?

Lesson 48 of 482