← Back to Book Detail

23 Dynamic Formatting (23/11) -- Patterns for Beginning Programmers

Browse
209%

23 Dynamic Formatting

23 Dynamic Formatting It is almost impossible to get this far in an introductory programming course without making extensive use of format specifiers (e.g., with the printf() method in the PrintWriter class or the format() method in the String class). However, most, if not all, of the format specifiers you have seen and/or used have probably been hard-coded. It turns out that there are many situations in which format specifiers must be created while a program is running. Motivation If you want to print all of the elements of a non-negative int[] in a field of width 10, it’s easy to do so using the format specifier "%10d" as follows: for (int i = 0; i < data.length; i++) { System.out.printf("%10d\n", data[i]); } However, now suppose, instead, that you want the field to be as narrow as possible. Since you can’t know the value of the elements of the array when you are writing the program, you can’t hard-code the format specifier. Review Fortunately, you already have some patterns that can help you solve this problem. First, from the discussion of accumulators in Chapter 13, you know that you can find the largest int in an int[] named data as follows: max = -1; for (int i = 0; i < data.length; i++) { if (data[i] > max) max = data[i]; } Second, from the discussion of digit counting in Chapter 11, you know that you can find the number of digits in an int value named max as follows: width = (int) (Math.log10(max)) + 1; So, all you need to complete the solution to the dynamic formatting problem is a format specifier. Thinking About The Problem Fortunately, the format specifier is a String object, and you can construct and manipulate String objects while a program is running. For example, returning to the situation in which you want to use a field of width 10 , you could use a String variable named fs for the format String as follows: fs = "%10d\n"; for (int i = 0; i < data.length; i++) { System.out.printf(fs, data[i]); } Now, all you need to do is replace the hard-coded 10 in fs with the value contained in a variable. The Pattern In particular, what you need to do is use String concatenation (or a StringBuilder object) to construct the format String . Recall that a format specifier has the following syntax: %[flags][width][.precision]conversion where: - flags is one or more of: - to indicate left-justification,+ to indicate required inclusion of the sign,, to include grouping separators, etc. - width indicates the width of the field - precision indicates the number of digits to the right of the decimal point for real numbers - conversion is one of b for aboolean ,c for achar ,d for an integer,f for a real number,s for aString , etc. and items in square brackets are optional. So, assuming all of the variables have been declared, you can construct a format specifier at run-time as follows: fs = "%"; if (flags != null) fs += flags; if (width > 0) fs += width; if (precision > 0) fs += "." + precision; fs += conversion; Examples Suppose you want to illustrate
← Previous Chapter Next Chapter →