Search code examples
javaprintfoutputsystem.out

Formatting java strings with system.out.printf


I've been looking around at a lot of questions about the System.out.printf in java for formatting string outputs and I just don't seem to understand how to use it.

I'm trying to print nice columns that looks like this

601 GoPro Hero5 Black       276.95
602 GoPro Hero5 Session     199.00
611 Canon EOS Rebel         361.89

but the best I can get is this

601 GoPro Hero5 Black     276.95
602 GoPro Hero5 Session     199.00
611 Canon EOS Rebel     361.89

I seem to be able to align the first two values but never the third. Here is my code

System.out.printf("%-1s %10s %10.2f\n", "ex string", "ex string", 276.95);

I thought the "-1s" was left align for minus, and 1 would be the space between the first and second input, then %10s would be ten characters apart, the %10.2 would be ten apart with 2 decimal places. So I tried to do

System.out.printf("%-1s %10s %20.2f\n", "ex string", "ex string", 276.95);

but this still doesn't get those third values inline with one another.


Revised attempt using

System.out.printf("%-10s %-10s %10.2f\n", "ex string", "ex string", 276.95);

results in...

601        GoPro Hero5 Black     276.95
602        GoPro Hero5 Session     199.00
611        Canon EOS Rebel     361.89

for the record my code is getting the variables like this:

System.out.printf("%-10s %-10s %10.2f\n", items.get(i).getItemNumber(), items.get(i).getName(), items.get(i).getPrice());

Solution

  • The field width specifiers are not spacing specs.

    %-1 means left align in a field at least one character wide. But your first column is always at least 3 characters wide, so the specifier is ignored. The first column comes out looking neat purely by coincidence: all your numbers happen to have three digits.

    Similarly, %10 means right align in a field at least 10 characters wide. But all your camera names are much longer than that, so the specifier is effectively ignored.

    You are probably looking for something more like

    %-4s%-25s%6.2f
    

    This means:

    1. Left align the first argument in a field at least 4 characters wide
    2. Left align the second argument in a field at least 25 characters wide
    3. Print the number right aligned, with two digits after the decimal point, in a field at least 6 characters wide

    You could replace %4s with %3s<space> for a similar effect. The difference would be in how overflow is handled. The first version would not have a space following values in the first column that were longer than 3 characters. The second one would.