Formatting with printf
String concatenation works well for
combining sever string literals and variables when no additional formatting is
required, but it can be cumbersome when there are many variables and doesn't
offer any tools for controlling how values are formatted. You can write your own
code to control formatting, but this can get repetitive and tedious. The
printf
function offers a better solution in these situations.
Look at the following code that prints the time for a 12-hour clock using concatenation:
String amOrPm = nextLine();
int hour = nextInt();
int minute = nextInt();
int second = nextInt();
String minuteFormatted;
if (minute < 10) {
minuteFormatted = "0" + minute;
} else {
minuteFormatted = "" + minute;
}
String secondFormatted;
if (second < 10) {
secondFormatted = "0" + second;
} else {
secondFormatted = "" + second;
}
String time = hour + ":" + minuteFormatted + ":" + secondFormatted + " " + amOrPm;
println(time);
This code works, but it has the drawbacks we just mentioned: the concatenated
string expression is long and hard to read due to all of the breaks in the
string literals and +
symbols joining the different parts, and we have to
write additional code to control how some of the numbers are formatted.
Compare this to using the printf
function:
String amOrPm = nextLine();
int hour = nextInt();
int minute = nextInt();
int second = nextInt();
printf("%d:%02d:%02d %s\n", hour, minute, second, amOrPm);
This produces the same output, but with far less code. The downside is that we may not know how to read the format string at the beginning. Let's fix that!
Format Strings and Args
The printf
function takes a format string that includes placeholder values for
any variables that we want to insert into the string. After this format string,
we include a list of arguments (the values we want to insert) in the same order
that their placeholders appear in the string.
It's also important to note that printf
, unlike println
, does not
automatically add a line break to the end of its output. If we want a line
break, and we usually do, then we need to include the \n
escape sequence in the format string.
Formatting Specifiers
The placeholders are "formatting specifiers," and their job is to convey the type of value to insert into the string as well as how we want to format that value. A formatting specifier has two or three parts:
- They begin with a percent sign
%
- They can (but don't have to) include some formatting information in the
middle, such as the
02
in our time example - They end in a character that represents the type of value we're going to
insert at that point in the string, such as
d
(decimal, as in "base-10", integer) ors
(string)
Interpreting Our Example
With all this in mind, how do we interpret the "%d:%02d:%02d %s"
from our
time example?
- Each
%d
represents an integer - A
%02d
is an integer with additional formatting: if it's shorter than2
characters then it should be padded with0
s so that it takes up2
characters of space - A
%s
is a string (the "AM"/"PM" value) - The colons (
:
) and space are not part of any placeholder values, so they'll be printed as they appear in the string
Let's apply these rules and see what our string looks like if hour
is 9
,
minute
is 5
, second
is 30
, and amOrPm
is "AM"
:
hour
is the first argument, so it takes the place of the%d
:"9:%02d:%02d %s"
minute
is the second argument, so it takes the place of the first%02d
, and because%02d
specifies that we pad with0
to ensure our number is at least2
characters long, we change the5
to05
:"9:05:%02d %s"
second
is the third argument, so it takes the place of the second%02d
:"9:05:30 %s"
amOrPm
is the last argument, so it takes the place of the%s
at the end of the format string:"9:05:30 AM"
Documentation
This example showed a few of the many types and methods for formatting those
types that printf
supports. Java has detailed documentation for
formatting strings, and there are also some tutorials
that you may find helpful. Not all
of this documentation is going to make sense early on, but the more you use
printf
and check the documentation, the better you'll be able to use Java's
documentation to find the information you need.