Formatting


When a human-readable form of a built-in type, such as int or double, is needed, a string representation must be created. Although C# automatically supplies a default format for this representation, it is also possible to specify a format of your own choosing. For example, as you saw in Part I, it is possible to output numeric data using a dollars and cents format. A number of methods format data, including Console.WriteLine( ), String.Format( ), and the ToString( ) method defined for the numeric structure types. The same approach to formatting is used by all three; once you have learned to format data for one, you can apply it to the others.

Formatting Overview

Formatting is governed by two components: format specifiers and format providers. The form that the string representation of a value will take is controlled through the use of a format specifier. Thus, it is the format specifier that dictates how the human-readable form of the data will look. For example, to output a numeric value using scientific notation, you will use the E format specifier.

In many cases, the precise format of a value will be affected by the culture and language in which the program is running. For example, in the United States, money is represented in dollars. In Europe, money is represented in euros. To handle the cultural and language differences, C# uses format providers. A format provider defines the way that a format specifier will be interpreted. A format provider is created by implementing the IFormatProvider interface. Format providers are predefined for the built-in numeric types and many other types in the .NET Framework. In general, you can format data without having to worry about specifying a format provider, and format providers are not examined further in this book.

To format data, you include a format specifier in a call to a method that supports formatting. The use of format specifiers was introduced in Chapter 3, but is worthwhile reviewing here. The discussion that follows uses Console.WriteLine( ), but the same basic approach applies to other methods that support formatting.

To format data using WriteLine( ), use the version of WriteLine( ) shown here:

 WriteLine(“format string”, arg0, arg1, , argN);

In this version, the arguments to WriteLine( ) are separated by commas and not + signs. The format string contains two items: regular, printing characters that are displayed as-is, and format commands.

Format commands take this general form:

 {argnum, width: fmt}

Here, argnum specifies the number of the argument (starting with zero) to display. The minimum width of the field is specified by width, and the format specifier is represented by fmt. Both width and fmt are optional. Thus, in its simplest form, a format command simply indicates which argument to display. For example, {0} indicates arg0, {1} specifies arg1, and so on.

During execution, when a format command is encountered in the format string, the corresponding argument, as specified by argnum, is substituted and displayed. Thus, it is the position of a format specification within the format string that determines where its matching data will be displayed. It is the argument number that determines which argument will be formatted.

If fmt is present, then the data is displayed using the specified format. Otherwise, the default format is used. If width is present, then output is padded with spaces to ensure that the minimum field width is attained. If width is positive, output is right-justified. If width is negative, output is left-justified.

The remainder of this chapter examines formatting and format specifiers in detail.

The Numeric Format Specifiers

There are several format specifiers defined for numeric data. They are shown in Table 21-4. Each format specifier can include an optional precision specifier. For example, to specify that a value be represented as a fixed-point value with two decimal places, use F2.

Table 21-4: The Format Specifiers

Specifier

Format

Meaning of Precision Specifier

C

Currency (that is, a monetary value).

Specifies the number of decimal places.

c

Same as C.

 

D

Whole number numeric data. (Use with integers only.)

Minimum number of digits. Leading zeros will be used to pad the result, if necessary.

d

Same as D.

 

E

Scientific notation (uses uppercase E).

Specifies the number of decimal places. The default is six.

e

Scientific notation (uses lowercase e).

Specifies the number of decimal places. The default is six.

F

Fixed-point notation.

Specifies the number of decimal places.

f

Same as F.

 

G

Use either E or F format, whichever is shorter.

See E and F.

g

Use either e or f format, whichever is shorter.

See e and f.

N

Fixed-point notation, with comma separators.

Specifies the number of decimal places.

n

Same as N.

 

P

Percentage.

Specifies the number of decimal places.

p

Same as P.

R

Numeric value that can be parsed, using Parse( ), back into its equivalent internal form. (This is called the “round-trip” format.)

Not used.

r

Same as R.

 

X

Hexadecimal (uses uppercase letters A through F).

Minimum number of digits. Leading zeros will be used to pad the result, if necessary.

x

Hexadecimal (uses lowercase letters a through f).

Minimum number of digits. Leading zeros will be used to pad the result if necessary.

As explained, the precise effect of certain format specifiers depends upon the cultural settings. For example, the currency specifier, C, automatically displays a value in the monetary format of the selected culture. For most users, the default cultural information matches their locale and language. Thus, the same format specifier can be used without concern about the cultural context in which the program is executed.

Here is a program that demonstrates several of the numeric format specifiers:

 // Demonstrate various format specifiers. using System; class FormatDemo {   public static void Main() {     double v = 17688.65849;     double v2 = 0.15;     int x = 21;     Console.WriteLine("{0:F2}", v);     Console.WriteLine("{0:N5}", v);     Console.WriteLine("{0:e}", v);     Console.WriteLine("{0:r}", v);     Console.WriteLine("{0:p}", v2);     Console.WriteLine("{0:X}", x);     Console.WriteLine("{0:D12}", x);          Console.WriteLine("{0:C}", 189.99);   } }

The output is shown here:

 17688.66 17,688.65849 1.768866e+004 17688.65849 15.00 % 15 000000000021 $189.99

Notice the effect of the precision specifier in several of the formats.

Understanding Argument Numbers

It is important to understand that the argument associated with a format specifier is determined by the argument number, not the argument’s position in the argument list. This means the same argument can be output more than once within the same call to WriteLine( ). It also means that arguments can be displayed in a sequence differently than they are specified in the argument list. For example, consider the following program:

 using System; class FormatDemo2 {   public static void Main() {     // Format the same argument three different ways:     Console.WriteLine("{0:F2}  {0:F3}  {0:e}", 10.12345);     // Display arguments in non-sequential order.     Console.WriteLine("{2:d} {0:d} {1:d}", 1, 2, 3);   } }

The output is shown here:

 10.12  10.123  1.012345e+001 3 1 2

In the first WriteLine( ) statement, the same argument, 10.12345, is formatted three different ways. This is possible because each format specifier refers to the first (and only) argument. In the second WriteLine( ) statement, the three arguments are displayed in non-sequential order. Remember, there is no rule that format specifiers must use the arguments in sequence. Any format specifier can refer to any argument.




C# 2.0(c) The Complete Reference
C# 2.0: The Complete Reference (Complete Reference Series)
ISBN: 0072262095
EAN: 2147483647
Year: 2006
Pages: 300

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