📄 printfformat.java
字号:
* if the precision is 0 and the # flag is not
* specified, no radix character appears. The
* E conversion will produce a number with E
* instead of e introducing the exponent. The
* exponent always contains at least two digits.
* However, if the value to be written requires
* an exponent greater than two digits,
* additional exponent digits are written as
* necessary. The value is rounded to the
* appropriate number of digits.
* <dt>g,G<dd>The floating point number argument is
* written in style f or e (or in sytle E in the
* case of a G conversion character), with the
* precision specifying the number of
* significant digits. If the precision is
* zero, it is taken as one. The style used
* depends on the value converted: style e
* (or E) will be used only if the exponent
* resulting from the conversion is less than
* -4 or greater than or equal to the precision.
* Trailing zeros are removed from the result.
* A radix character appears only if it is
* followed by a digit.
* <dt>c,C<dd>The integer argument is converted to a
* char and the result is written.
*
* <dt>s,S<dd>The argument is taken to be a string and
* bytes from the string are written until the
* end of the string or the number of bytes
* indicated by the precision specification of
* the argument is reached. If the precision
* is omitted from the argument, it is taken to
* be infinite, so all characters up to the end
* of the string are written.
* <dt>%<dd>Write a % character; no argument is
* converted.
*</dl>
*<p>
* If a conversion specification does not match one of
* the above forms, an IllegalArgumentException is
* thrown and the instance of PrintfFormat is not
* created.</p>
*<p>
* If a floating point value is the internal
* representation for infinity, the output is
* [+]Infinity, where Infinity is either Infinity or
* Inf, depending on the desired output string length.
* Printing of the sign follows the rules described
* above.</p>
*<p>
* If a floating point value is the internal
* representation for "not-a-number," the output is
* [+]NaN. Printing of the sign follows the rules
* described above.</p>
*<p>
* In no case does a non-existent or small field width
* cause truncation of a field; if the result of a
* conversion is wider than the field width, the field
* is simply expanded to contain the conversion result.
*</p>
*<p>
* The behavior is like printf. One exception is that
* the minimum number of exponent digits is 3 instead
* of 2 for e and E formats when the optional L is used
* before the e, E, g, or G conversion character. The
* optional L does not imply conversion to a long long
* double. </p>
* <p>
* The biggest divergence from the C printf
* specification is in the use of 16 bit characters.
* This allows the handling of characters beyond the
* small ASCII character set and allows the utility to
* interoperate correctly with the rest of the Java
* runtime environment.</p>
*<p>
* Omissions from the C printf specification are
* numerous. All the known omissions are present
* because Java never uses bytes to represent
* characters and does not have pointers:</p>
*<ul>
* <li>%c is the same as %C.
* <li>%s is the same as %S.
* <li>u, p, and n conversion characters.
* <li>%ws format.
* <li>h modifier applied to an n conversion character.
* <li>l (ell) modifier applied to the c, n, or s
* conversion characters.
* <li>ll (ell ell) modifier to d, i, o, u, x, or X
* conversion characters.
* <li>ll (ell ell) modifier to an n conversion
* character.
* <li>c, C, d,i,o,u,x, and X conversion characters
* apply to Byte, Character, Short, Integer, Long
* types.
* <li>f, e, E, g, and G conversion characters apply
* to Float and Double types.
* <li>s and S conversion characters apply to String
* types.
* <li>All other reference types can be formatted
* using the s or S conversion characters only.
*</ul>
* <p>
* Most of this specification is quoted from the Unix
* man page for the sprintf utility.</p>
*
* @author Allan Jacobs
*
* @version $Revision: 1.9 $
*
* @since 6.0.0
*/
public class PrintfFormat {
/**
*<p>
* ConversionSpecification allows the formatting of
* a single primitive or object embedded within a
* string. The formatting is controlled by a
* format string. Only one Java primitive or
* object can be formatted at a time.
*<p>
* A format string is a Java string that contains
* a control string. The control string starts at
* the first percent sign (%) in the string,
* provided that this percent sign
*<ol>
*<li>is not escaped protected by a matching % or
* is not an escape % character,
*<li>is not at the end of the format string, and
*<li>precedes a sequence of characters that parses
* as a valid control string.
*</ol>
*<p>
* A control string takes the form:
*<pre> % ['-+ #0]* [0..9]* { . [0..9]* }+
* { [hlL] }+ [idfgGoxXeEcs]
*</pre>
*<p>
* The behavior is like printf. One (hopefully the
* only) exception is that the minimum number of
* exponent digits is 3 instead of 2 for e and E
* formats when the optional L is used before the
* e, E, g, or G conversion character. The
* optional L does not imply conversion to a long
* long double.
*/
private final class ConversionSpecification {
/** Default precision. */
private static final int DEFAULT_DIGITS = 6;
/**
* For an o conversion, increase the precision to
* force the first digit of the result to be a
* zero. For x (or X) conversions, a non-zero
* result will have 0x (or 0X) prepended to it.
* For e, E, f, g, or G conversions, the result
* will always contain a radix character, even if
* no digits follow the point. For g and G
* conversions, trailing zeros will not be removed
* from the result.
*/
private boolean m_alternateForm;
/** Internal variable. */
private int m_argumentPosition;
/** Internal variable. */
private int m_argumentPositionForFieldWidth;
/** Internal variable. */
private int m_argumentPositionForPrecision;
/** Control string type. */
private char m_conversionCharacter;
/**
* If the converted value has fewer bytes than the
* field width, it will be padded with spaces or
* zeroes.
*/
private int m_fieldWidth;
/**
* Flag indicating whether or not the field width
* has been set.
*/
private boolean m_fieldWidthSet;
/** Literal or control format string. */
private String m_fmt;
/**
* The result of a signed conversion will always
* begin with a sign (+ or -).
*/
private boolean m_leadingSign;
/**
* Flag indicating that left padding with spaces is
* specified.
*/
private boolean m_leadingSpace;
/**
* Flag indicating that left padding with zeroes is
* specified.
*/
private boolean m_leadingZeros;
/**
* The result of the conversion will be
* left-justified within the field.
*/
private boolean m_leftJustify;
/**
* Flag specifying that a following d, i, o, u, x,
* or X conversion character applies to a type
* short int.
*/
private boolean m_optionalh;
/**
* Flag specifying that a following d, i, o, u, x,
* or X conversion character applies to a type lont
* int argument.
*/
private boolean m_optionall;
/**
* Flag specifying that a following e, E, f, g, or
* G conversion character applies to a type double
* argument. This is a noop in Java.
*/
private boolean m_optionalL;
/**
* Position within the control string. Used by
* the constructor.
*/
private int m_pos;
/** Internal variable. */
private boolean m_positionalFieldWidth;
/** Internal variable. */
private boolean m_positionalPrecision;
/** Internal variable. */
private boolean m_positionalSpecification;
/**
* The minimum number of digits to appear for the
* d, i, o, u, x, or X conversions. The number of
* digits to appear after the radix character for
* the e, E, and f conversions. The maximum number
* of significant digits for the g and G
* conversions. The maximum number of bytes to be
* printed from a string in s and S conversions.
*/
private int m_precision;
/**
* Flag indicating whether or not the precision has
* been set.
*/
private boolean m_precisionSet;
/**
* The integer portion of the result of a decimal
* conversion (i, d, u, f, g, or G) will be
* formatted with thousands' grouping characters.
* For other conversions the flag is ignored.
*/
private boolean m_thousands;
/**
* Flag indicating that the field width is *.
*/
private boolean m_variableFieldWidth;
/**
* Flag indicating that the precision is *.
*/
private boolean m_variablePrecision;
/**
* Constructor. Used to prepare an instance
* to hold a literal, not a control string.
*/
private ConversionSpecification() {
// empty
}
/**
* Constructor for a conversion specification.
* The argument must begin with a % and end
* with the conversion character for the
* conversion specification.
* @param fmtArg String specifying the
* conversion specification.
* @exception CmsIllegalArgumentException if the
* input string is null, zero length, or
* otherwise malformed.
*/
private ConversionSpecification(String fmtArg)
throws CmsIllegalArgumentException {
if (fmtArg == null) {
throw new NullPointerException();
}
if (fmtArg.length() == 0) {
throw new CmsIllegalArgumentException(Messages.get().container(Messages.ERR_CONTROL_STRING_LENGTH_0));
}
if (fmtArg.charAt(0) == '%') {
m_fmt = fmtArg;
m_pos = 1;
setArgPosition();
setFlagCharacters();
setFieldWidth();
setPrecision();
setOptionalHL();
if (setConversionCharacter()) {
if (m_pos == fmtArg.length()) {
if (m_leadingZeros && m_leftJustify) {
m_leadingZeros = false;
}
if (m_precisionSet && m_leadingZeros) {
if (m_conversionCharacter == 'd'
|| m_conversionCharacter == 'i'
|| m_conversionCharacter == 'o'
|| m_conversionCharacter == 'x') {
m_leadingZeros = false;
}
}
} else {
throw new CmsIllegalArgumentException(Messages.get().container(
Messages.ERR_INVALID_CONVERSION_SPEC_1,
fmtArg));
}
} else {
throw new CmsIllegalArgumentException(Messages.get().container(
Messages.ERR_INVALID_CONVERSION_SPEC_1,
fmtArg));
}
} else {
throw new CmsIllegalArgumentException(Messages.get().container(Messages.ERR_CONTROL_STRING_START_0));
}
}
/**
* Internal helper.<p>
*
* @return the result
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -