.NODE

Formatter

In fact, printf( ) is a little more general than System.out (though that's its primary justification). Besides printf( ), the PrintStream class also has a format( ) method:

public PrintStream format(String format, Object... args)

This does exactly the same thing as printf( ). That is, the previous example could be rewritten like this and produce identical output:

for (double degrees = 0.0; degrees < 360.0; degrees++) {
 double radians = Math.PI * degrees / 180.0;
 double grads = 400 * degrees / 360;
 System.out.format("%5.1f %5.1f %5.1f
", degrees , radians, grads);
}

Why two methods, then? The format( ) method is used not just by PrintStream but also by the java.util.Formatter class:

public class Formatter implements Flushable, Closeable

printf( ) is there solely to make C programmers feel nostalgic.

Formatter is the object-oriented equivalent of sprintf( ) and fprintf( ) in C. Rather than writing its output onto the console, it writes it into a string, a file, or an output stream. Pass the object you want to write into to the Formatter constructor. For example, this code fragment creates a Formatter that writes data into a file named angles.txt:

Formatter formatter = new Formatter("angles.txt");

Once you've created a Formatter object, you can write to it using the format( ) method just as you would with System.out.format( ), except that the output goes into the file rather than onto the console:

for (double degrees = 0.0; degrees < 360.0; degrees++) {
 double radians = Math.PI * degrees / 180.0;
 double grads = 400 * degrees / 360;
 formatter.format("%5.1f %5.1f %5.1f
", degrees , radians, grads);
}

Formatters are not output streams, but they can and should be flushed and closed just the same:

formatter.flush( );
formatter.close( );

 

7.5.1. Constructors

Exactly where the output from a Formatter ends up depends on what argument you pass to the constructor. You've already seen the constructor that takes a filename:

public Formatter(String fileName) throws FileNotFoundException

If the named file does not exist in the current working directory, this constructor attempts to create it. If that fails for any reason other than a security violation, the constructor throws a FileNotFoundException. Security problems are reported with a SecurityException instead. If the file does exist, its contents are overwritten.

Instead of a filename, you can pass in a File object:

public Formatter(File file) throws FileNotFoundException

You can also use a Formatter to write onto a PrintStream or another kind of OutputStream:

public Formatter(PrintStream out)
public Formatter(OutputStream out)

or onto any Appendable object:

public Formatter(Appendable out)

The Appendable interface is a new Java 5 interface for anything onto which chars can be appended. This includes StringBuffers and StringBuilders. It also includes a number of classes we'll talk about later, such as CharBuffer and Writer.

Finally, the no-args constructor creates a Formatter with no specified destination for output:

public Formatter( )

In this case, the Formatter writes everything onto a new StringBuilder object. You can retrieve this object using the out( ) method at any time before the Formatter is closed:

public Appendable out( ) throws FormatterClosedException

You might need to use this method if you want to write unformatted output onto the same StringBuilder, but more commonly you'll just use the toString( ) method to get the final result. For example:

Formatter formatter = new Formatter( );
for (double degrees = 0.0; degrees < 360.0; degrees++) {
 double radians = Math.PI * degrees / 180.0;
 double grads = 400 * degrees / 360;
 formatter.format("%5.1f %5.1f %5.1f
", degrees , radians, grads);
}
String table = formatter.toString( );

 

7.5.2. Character Sets

So far, I haven't paid a lot of attention to character set issues. As long as you stick to the ASCII character set, a single computer, and System.out, character sets aren't likely to be a problem. However, as data begins to move between different systems, it becomes important to consider what happens when the other systems use different character sets. For example, suppose I use a Formatter or a PrintStream on a typical U.S. or Western European PC to write the sentence "Au cours des dernières années, XML a été adapte dans des domaines aussi diverse que l'aéronautique, le multimédia, la gestion de hôpitaux, les télécommunications, la théologie, la vente au détail, et la littérature médiévale" in a file. Say I then send this file to a Macintosh user, who opens it up and sees "Au cours des derniËres annÈes, XML a ÈtÈ adapte dans des domaines aussi diverse que l'aÈronautique, le multimÈdia, la gestion de hÙpitaux, les tÈlÈcommunications, la thÈologie, la vente au dÈtail, et la littÈrature mÈdiÈvale." This is not the same thing at all! The confusion is even worse if you go in the other direction.

If you're writing to the console (i.e., System.out), you don't really need to worry about character set issues. The default character set Java writes in is usually the same one the console uses.

Actually, you may need to worry a little. On Windows, the console encoding is usually not the same as the system encoding found in the file.encoding system property. In particular, the console uses a DOS character set such as Cp850 that includes box drawing characters such as and , while the rest of the system uses an encoding such as Cp1252 that maps these same code points to alphabetic characters like È and Î. To be honest, the console is reliable enough for ASCII, but anything beyond that requires a GUI.

However, there's more than one character set, and when transmitting files between systems and programs, it pays to be specific. In the previous example, if we knew the file was going to be read on a Macintosh, we might have specified that it be written with the MacRoman encoding:

Formatter formatter = new Formatter("data.txt", "MacRoman");

More likely, we'd just agree on both the sending and receiving ends to use some neutral format such as ISO-8859-1 or UTF-8. In some cases, encoding details can be embedded in the file you write (HTML, XML) or sent as out-of-band metadata (HTTP, SMTP). However, you do need some way of specifying and communicating the character set in which any given document is written. When you're writing to anything other than the console or a string, you should almost always specify an encoding explicitly. Three of the Formatter constructors take character set names as their second argument:

public Formatter(String fileName, String characterSet)
 throws FileNotFoundException
public Formatter(File file , String characterSet)
 throws FileNotFoundException
public Formatter(OutputStream out, String characterSet)

I'll have more to say about character sets in Chapter 19.

7.5.3. Locales

Character sets are not the only localization issue in the Formatter class. For instance, in France, a decimal comma is used instead of a decimal point. Thus, a French user running the earlier degree table example would want to see this:

0,0 0,0 0,0
1,0 0,0 1,1
2,0 0,0 2,2
3,0 0,1 3,3
4,0 0,1 4,4
...

Sometimes Java adapts the format to the local conventions automatically, and sometimes it doesn't. For instance, if you want decimal commas, you have to write %,5.1f instead of %5.1f. The comma after the percent sign is a flag that tells the formatter to use the local conventions. (It does not actually say to use commas.) Java will now use commas only if the local conventions say to use commas. On a typical U.S. English system, the local convention is a decimal point, and that's what you'll get even if you format numbers as %,5.1f.

Of course, sometimes you don't want a program to adapt to the local conventions. For instance, many companies use PCs adapted to local languages and customs but still need to produce English documents that use American formats. Thus, as an optional third argument to the constructor, you can pass a java.util.Locale object:

public Formatter(String fileName, String characterSet, Locale locale)
 throws FileNotFoundException
public Formatter(File file, String characterSet, Locale locale)
 throws FileNotFoundException
public Formatter(OutputStream out, String characterSet, Locale locale)

For example, to force the use of American conventions regardless of where a program is run, you'd construct a Formatter like this:

Formatter formatter = new Formatter("data.txt", "ISO-8859-1", Locale.US);

You can also specify a locale when writing to an Appendable object or a StringBuilder:

public Formatter(Appendable out, Locale locale)
public Formatter(Locale locale)

Character encodings don't matter for these two cases because both Appendable and StringBuilder are defined in terms of characters rather than bytesthere's no conversion to be done. However, locales can change formatting even when the character set stays the same.

On occasion, you might wish to change the locale for one string you write but not for other strings (in a mixed English/French document, perhaps). In that case, you can pass a locale as the first argument to the format( ) method before the format string:

public Formatter format(Locale locale, String format, Object... args)

You can do the same thing with the printf( ) and format( ) methods in the PrintStream class:

public PrintStream printf(Locale locale, String format, Object... args)

Finally, I'll note that there's a getter method that returns the Formatter's current locale:

public Locale locale( )

 

7.5.4. Error Handling

The Formatter class handles errors in much the same way PrintStream does. That is, it sweeps them under the rug and pretends they didn't happen. Notice how none of the methods mentioned so far threw IOException?

To find out if the Formatter has encountered an error, invoke its ioException( ) method:

public IOException ioException( )

This returns the last IOException thrown by the underlying output stream. If there was more than one, only the last one is available.

This is marginally better than PrintStream's boolean checkError( ) method. At least Formatter will tell you what the problem was. However, it still won't tell you unless you ask. For simple cases in which you don't have to write a lot of data before closing the Formatter and checking for any errors, this may be adequate. However, programs that need to write for an extended period of time should probably create strings using a Formatter but write them using a regular OutputStream. That way, if an I/O error does happen, you'll find out soon enough to do something about it.

7.5.5. Format Specifiers

The Formatter class and the printf( ) method in PrintStream that depends on it support several dozen format specifiers. In addition to integer and floating-point numbers, Formatter offers a wide range of date and time formats. It also has a few general formatters that can display absolutely any object or primitive data type.

All format specifiers begin with percent signs. The minimum format specifier is a percent sign followed by an alphabetic conversion code. This code identifies what the corresponding argument is to be formatted as. For instance, %f formats a number with a decimal point, %d formats it as a decimal (base-10) integer, %o formats it as an octal integer, and %x formats it as a hexadecimal integer. None of these specifiers changes what the number actually is; they're just different ways of creating a string that represents the number.

To use a literal percent character in a format string, just double escape it. That is, %% is formatted as % in the output.

To get the platform default line separator, use %n. ( is always a linefeed regardless of platform. %n may be a carriage return, a linefeed, or a carriage return linefeed pair, depending on the platform.)

 

7.5.5.1. Integer conversions

Integer conversions can be applied to all integral types (specifically, byte, short, int, and long, as well as the type-wrapper classes Byte, Short, Integer, Long, and also the java.math.BigInteger class). These conversions are:

 

%d

A regular base-10 integer, such as 987

 

%o

A base-8 octal integer, such as 1733

 

%x

A base-16 lowercase hexadecimal integer, such as 3db

 

%X

A base-16 uppercase hexadecimal integer, such as 3DB

Example 7-1 prints the number 1023 in all four formats.

Example 7-1. Integer format specifiers

public class IntegerFormatExample {
 public static void main(String[] args) {
 int n = 1023;
 System.out.printf("Decimal: %d
", n);
 System.out.printf("Octal: %o
", n);
 System.out.printf("Lowercase hexadecimal: %x
", n);
 System.out.printf("Uppercase hexadecimal: %X
", n);
 }
}

Here's the output:

Decimal: 1023
Octal: 1777
Lowercase hexadecimal: 3ff
Uppercase hexadecimal: 3FF

 

7.5.5.2. Floating-point conversions

Floating-point conversions can be applied to all floating-point types: float and double, the type-wrapper classes Float and Double, and java.math.BigDecimal. These conversions are:

 

%f

A regular base-10 decimal number, such as 3.141593

 

%e

A decimal number in scientific notation with a lowercase e, such as 3.141593e+00

 

%E

A decimal number in scientific notation with an uppercase E, such as 3.141593E+00

 

%g

A decimal number formatted in either regular or scientific notation, depending on its size and precision, with a lowercase e if scientific notation is used

 

%G

A decimal number formatted in either regular or scientific notation, depending on its size and precision, with an uppercase E if scientific notation is used

 

%a

A lowercase hexadecimal floating-point number, such as 0x1.921fb54442d18p1

 

%A

An uppercase hexadecimal floating-point number, such as 0X1.921FB54442D18P1

Surprisingly, you cannot use these conversions on integer types such as int or BigDecimal. Java will not automatically promote the integer type to a floating-point type when formatting. If you try to use them, it throws an IllegalFormatConversionException.

Example 7-2 prints p in all of these formats.

Example 7-2. Floating-point format specifiers

public class FloatingPointFormatExample {
 public static void main(String[] args) {
 System.out.printf("Decimal: %f
", Math.PI);
 System.out.printf("Scientific notation: %e
", Math.PI);
 System.out.printf("Scientific notation: %E
", Math.PI);
 System.out.printf("Decimal/Scientific: %g
", Math.PI);
 System.out.printf("Decimal/Scientific: %G
", Math.PI);
 System.out.printf("Lowercase Hexadecimal: %a
", Math.PI);
 System.out.printf("Uppercase Hexadecimal: %A
", Math.PI);
 }
}

Here's the output:

Decimal: 3.141593
Scientific notation: 3.141593e+00
Scientific notation: 3.141593E+00
Decimal/Scientific: 3.14159
Decimal/Scientific: 3.14159
Lowercase Hexadecimal: 0x1.921fb54442d18p1
Uppercase Hexadecimal: 0X1.921FB54442D18P1

 

7.5.5.3. Date and time conversions

Date and time conversions can be applied to java.util.Calendar and java.util.Date objects. They can also be applied to long and Long values, in which case the value is assumed to be the number of milliseconds since midnight, January 1, 1970. All date and time conversions begin with a t for lowercase or a T for uppercase. These conversions are:

 

%tH /% TH

Two-digit hour using a 24-hour clock, ranging from 00 to 23

 

%tI / % TI

Two-digit hour using a 12-hour clock, ranging from 01 to 12

 

%tk / %Tk

One- or two-digit hour using a 24-hour clock, ranging from 0 to 23

 

%tl / %Tl

One- or two-digit hour using a 12-hour clock, ranging from 1 to 12

 

%tM / %TM

Two-digit minutes, ranging from 00 to 59

 

%tS / %TS

Two-digit seconds, ranging from 00 to 60 (60 is used for leap seconds)

 

%tL / %TL

Three-digit milliseconds, ranging from 000 to 999

 

%tN / %TN

Nine-digit nanoseconds, ranging from 000000000 to 999999999

 

%tp / %Tp

Locale-specific morning/afternoon indicator, such as am or PM

 

%tz / %Tz

RFC 822 numeric time zone indicator as an offset from UMT (for instance, Eastern Standard Time is -0500)

 

%tZ / %TZ

An abbreviation for the time zone, such as edt or EST

 

%ts / %Ts

Seconds elapsed since midnight, January 1, 1970, Greenwich Mean Time

 

%TQ

Milliseconds elapsed since midnight, January 1, 1970, Greenwich Mean Time

 

%tB / %TB

Localized month, such as "January" or "JANVIER"

 

%tb / %Tb

Localized, abbreviated month, such as "Jan" or "JAN"

 

%th / %Th

Localized, abbreviated month, such as "Jan" or "JAN" (yes, %tb and %th are synonyms; I have no idea why)

 

%tA / %TA

Localized day name, such as "Tuesday" or "MARDI"

 

%ta / %Ta

Localized, abbreviated day, such as "Tue" or "TUE"

 

%tC / %TC

Two-digit century, ranging from 00 to 99

 

%tY / %TY

Year with at least four digits, ranging from 0001 to the indefinite future

 

%ty / %Ty

Two-digit year, ranging from 00 to 99

 

%tj / %Tj

Three-digit day of the year, ranging from 001 to 366

 

%tm / %Tm

Two-digit month, ranging from 01 to 13 (13 is used in some non-Gregorian lunar calendars)

 

%td / %Td

Two-digit day of the month, ranging from 01 to 31

 

%te / %Te

One- or two-digit day of the month, ranging from 1 to 31

 

%tR / %TR

Hours and minutes on a 24-hour clock, such as 03:23 or 14:07

 

%tT / %TT

Hours, minutes, and seconds on a 24-hour clock, such as 03:23:17 or 14:07:00

 

%tr / %Tr

Hours, minutes, and seconds on a 12-hour clock, such as 03:23:17 am or 02:07:00 PM

 

%tD / %TD

Date in the form month/day/year, such as 05/12/06

 

%tF / %TF

ISO 8601 standard date in the form year-month-day, such as 2006-05-12

 

%tc / %Tc

Date and time formatted like so: "Fri May 12 12:27:30 EDT 2006"

Example 7-3 prints the current date and time in all of these formats.

Example 7-3. Date format specifiers

import java.util.Date;
public class DateFormatExample {
 public static void main(String[] args) {
 Date now = new Date( );
 System.out.printf("two-digit hour on a 24-hour clock: %tH/%TH
", now, now);
 System.out.printf("two-digit hour on a 12-hour clock: %tI/%TI
", now, now);
 System.out.printf("one- or two-digit hour on a 24-hour clock: %tk/%Tk
",
 now, now);
 System.out.printf("one- or two-digit hour on a 12-hour clock: %tl/%Tl
", now,
 now);
 System.out.printf("two-digit minutes ranging from 00 to 59: %tH/%TH
",
 now, now);
 System.out.printf("two-digit seconds ranging from 00 to 60 : %tS/%TS
",
 now, now);
 System.out.printf("milliseconds: %tL/%TL
", now, now);
 System.out.printf("nanoseconds: %tN/%TN
", now, now);
 System.out.printf("locale-specific morning/afternoon indicator: %tp/%Tp
",
 now, now);
 System.out.printf("RFC 822 numeric time zone indicator: %tz/%Tz
", now, now);
 System.out.printf("time zone abbreviation: %tZ/%TZ
", now, now);
 System.out.printf("seconds since the epoch: %ts/%Ts
", now, now);
 System.out.printf("milliseconds since the epoch: %TQ
", now);
 System.out.printf("localized month name: %tB/%TB
", now, now);
 System.out.printf("localized, abbreviated month: %tb/%Tb
", now, now);
 System.out.printf("localized, abbreviated month: %th/%Th
", now, now);
 System.out.printf("localized day name: %tA/%TA
", now, now);
 System.out.printf("localized, abbreviated day: %ta/%Ta
", now, now);
 System.out.printf("two-digit century: %tC/%TC
", now, now);
 System.out.printf("four-digit year: %tY/%TY
", now, now);
 System.out.printf("two-digit year: %ty/%Ty
", now, now);
 System.out.printf("three-digit day of the year: %tj/%Tj
", now, now);
 System.out.printf("two-digit month: %tm/%Tm
", now, now);
 System.out.printf("two-digit day of the month: %td/%Td
", now, now);
 System.out.printf("one- or two-digit day of the month: %te/%Te
", now, now);
 System.out.printf("hours and minutes on a 24-hour clock: %tR/%TR
", now, now);
 System.out.printf("hours, minutes, and seconds on a 24-hour clock: %tT/%TT
",
 now, now);
 System.out.printf("hours, minutes, and seconds on a 12-hour clock: %tr/%Tr
",
 now, now);
 System.out.printf("month/day/year: %tD/%TD
", now, now);
 System.out.printf("ISO 8601 standard date: %tF/%TF
", now, now);
 System.out.printf("Unix date format: %tc/%Tc
", now, now);
 }
}

Here's the output when this was run on Friday, June 24, 2005 at 6:43 PM EDT:

two-digit hour on a 24-hour clock: 18/18
two-digit hour on a 12-hour clock: 06/06
one- or two-digit hour on a 24-hour clock: 18/18
one- or two-digit hour on a 12-hour clock: 6/6
two-digit minutes ranging from 00 to 59: 18/18
two-digit seconds ranging from 00 to 60 : 50/50
milliseconds: 859/859
nanoseconds: 859000000/859000000
locale-specific morning/afternoon indicator: pm/PM
RFC 822 numeric time zone indicator: -0500/-0500
time zone abbreviation: EDT/EDT
seconds since the epoch: 1119653030/1119653030
milliseconds since the epoch: 1119653030859
localized month name: June/JUNE
localized, abbreviated month: Jun/JUN
localized, abbreviated month: Jun/JUN
localized day name: Friday/FRIDAY
localized, abbreviated day: Fri/FRI
two-digit century: 20/20
four-digit year: 2005/2005
two-digit year: 05/05
three-digit day of the year: 175/175
two-digit month: 06/06
two-digit day of the month: 24/24
one- or two-digit day of the month: 24/24
hours and minutes on a 24-hour clock: 18:43/18:43
hours, minutes, and seconds on a 24-hour clock: 18:43:50/18:43:50
hours, minutes, and seconds on a 12-hour clock: 06:43:50 PM/06:43:50 PM
month/day/year: 06/24/05/06/24/05
ISO 8601 standard date: 2005-06-24/2005-06-24
Unix date format: Fri Jun 24 18:43:50 EDT 2005/FRI JUN 24 18:43:50 EDT 2005

 

7.5.5.4. Character conversions

Character conversions can be applied to char and java.lang.Character objects. They can also be applied to byte, short, int, and the equivalent type-wrapper objects if the integer falls into the range of Unicode code points (0 to 0x10FFFF). These conversions are:

 

%c

A lowercase Unicode character

 

%C

An uppercase Unicode character

7.5.5.5. Boolean conversions

Boolean conversions can be applied to boolean primitive values and java.lang.Boolean objects. They can also be applied to all object types, in which case they're considered to be true if the object is nonnull and false if it is null. All other primitive types are considered to be true, regardless of value. These conversions are:

 

%b

"true" or "false"

 

%B

"TRUE" or "FALSE"

These conversions are not localized. Even in France, you'll see "true" and "false" instead of "vrai" and "faux."

7.5.5.6. General conversions

There are two more conversions that can be applied to any object and also to primitive types after autoboxing. These are:

 

%h/%H

The lowercase/uppercase hexadecimal form of the object's hashCode, or "null" or "NULL" if the object is null.

 

%s/%S

The result of invoking the object's formatTo( ) method if it implements Formattable; otherwise, the result of invoking its toString( ) method, or "null" if the object is null. With %S, this value is then converted to uppercase.

Example 7-4 prints a URL (which does not implement Formattable) in all of these formats.

Example 7-4. General format specifiers

import java.net.*;
public class GeneralFormatExample {
 public static void main(String[] args) throws MalformedURLException {
 URL u = new URL("http://www.example.com/Article.html");
 System.out.printf("boolean: %b
", u);
 System.out.printf("BOOLEAN: %B
", u);
 System.out.printf("hashcode: %h
", u);
 System.out.printf("HASHCODE: %H
", u);
 System.out.printf("string: %s
", u);
 System.out.printf("STRING: %S
", u);
 }
}

Here's the output from running this on a U.S.-localized system:

boolean: true
BOOLEAN: TRUE
hashcode: 79d2cef0
HASHCODE: 79D2CEF0
string: http://www.example.com/Article.html
STRING: HTTP://WWW.EXAMPLE.COM/ARTICLE.HTML

Be cautious about uppercasing. URL path components and many other things are case sensitive. HTTP://WWW.EXAMPLE.ORG/ARTICLE.HTML is not the same URL as http://www.example.org/Article.html.

7.5.6. Format Modifiers

In addition to a conversion code, the format string can also specify a width, a precision, the argument it's replaced with, and any of several special-purpose flags. The most general format follows this pattern:

%[argument_index$][flags][width][.precision]conversion

Here is a quick definition of those parameters. More detail on each will follow:

 

argument_index

The number of the argument with which to replace this tag

 

flags

Indicators of various formatting options

 

width

The minimum number of characters with which to format the replacement value

 

precision

The number of characters after the decimal point; alternately, the maximum number of characters in the formatted string

These four options control exactly how a string is formatted as tags are replaced by values.

7.5.6.1. Argument index

The argument index is specified when the order of the arguments does not match the order of the tags. For example:

out.printf("There are %2$f centimeters in %1$f feet.", feet, 2.54 * feet * 12);

In this case, indexes start with 1 rather than 0, which is unusual for Java. (The format string counts as argument 0.) If you reference a nonexistent argument, printf( ) throws a MissingFormatArgumentException.

The argument index is particularly useful when you want to repeat the same value more than once in a string, perhaps formatted differently each time. For example:

System.out.printf("Hexadecimal: %1$H Decimal: %1$f", Math.PI);

You can also repeat the previous argument by specifying a less than sigh (<) rather than an integer and a dollar sign ($). For instance, this statement is equivalent to the previous statement:

System.out.printf("Hexadecimal: %1$H Decimal: %

7.5.6.2. Flags

Flags indicate a variety of formatting options. Not all flags apply to all types. Using a flag to format a type that does not apply throws a FormatFlagsConversionMismatchException, a subclass of IllegalFormatException. However, you can combine multiple flags that do apply. Table 7-1 summarizes these flags.

Table 7-1. Format flags

Flag

Signifies

Applies to

-

Left-justify.

All

#

Alternate form.

General, integer, floating point

+

Include a sign even if positive. (Normally, only negative numbers have signs.)

Integer, floating point

space

Add a leading space to positive numbers. (This is where the sign would be and helps line up positive and negative numbers.)

Integer, floating point

0

Pad with zeros instead of spaces.

Integer, floating point

,

Use the locale-specific grouping separator instead of a period.

Integer, floating point

(

Use instead of a minus sign to indicate negative numbers.

Integer, floating point

For example, this statement prints a double formatted as a 20-character decimal padded with zeros, using a locale-specific grouping separator and parentheses for negative numbers:

System.out.printf("%(+0,20f", -Math.PI);

 

The result is (00000000003.141593).

The relative order of the flags does not matter. This statement prints the same thing:

System.out.printf("%,0+(20f", -Math.PI);

 

7.5.6.3. Width

Each of the various conversions may be preceded by an optional width. This sets the minimum number of characters to print. For example, if you format an integer using the code %5d, it will always be printed at least five characters wide. If the integer has fewer than five digits, extra spaces are added on the left-hand side to make up five characters. If it has five or more digits, no extra spaces are added.

The entire number is always printed. If the argument is larger than can fit in five places, all of it will be printed anyway, and subsequent columns may no longer line up properly.

 

For example, this statement prints five mathematical constants, each 12 places wide:

System.out.printf("%12f %12f %12f %12f %12f",
 Math.PI, Math.E, 1.0, 0.0, Math.sqrt(2));

 

By default, extra places are filled with space characters to right-justify the numbers. However, flags can be used to fill extra places with zeros or to left-justify the numbers instead.

This is the output:

3.141593 2.718282 1.000000 0.000000 1.414214

 

Width is not limited to numeric types. You can specify a width for any format tag: date, time, boolean, and so on.

7.5.6.4. Precision

Floating-point types (%e, %E, %f, %g, and %G) may also specify a precision in the form .3 or .5. The precision comes after the width but before the conversion code. This indicates how many places are used after the decimal point. For example, this statement formats the same five constants 15 places wide, with 3 places after the decimal point:

System.out.printf("%15.3f %15.3f %15.3f %15.3f %15.3f",
 Math.PI, Math.E, 1.0, 0.0, Math.sqrt(2));

 

This is the output:

3.142 2.718 1.000 0.000 1.414

 

A precision can also be applied to strings and other nonnumeric, nondate types. In these cases, it specifies the maximum number of characters to write to the output.

Precision cannot be set for integral types, however. Attempting to do so throws an IllegalFormatPrecisionException. As usual, this is a subclass of IllegalFormatException and a runtime exception.

Basic I/O

Introducing I/O

Output Streams

Input Streams

Data Sources

File Streams

Network Streams

Filter Streams

Filter Streams

Print Streams

Data Streams

Streams in Memory

Compressing Streams

JAR Archives

Cryptographic Streams

Object Serialization

New I/O

Buffers

Channels

Nonblocking I/O

The File System

Working with Files

File Dialogs and Choosers

Text

Character Sets and Unicode

Readers and Writers

Formatted I/O with java.text

Devices

The Java Communications API

USB

The J2ME Generic Connection Framework

Bluetooth

Character Sets





Java I/O
Java I/O
ISBN: 0596527500
EAN: 2147483647
Year: 2004
Pages: 244
Similar book on Amazon

Flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net