 .NET 1.1C# Numeric String Conversion Part 2
The nineteenth part of the C# Fundamentals tutorial continues the examination of conversion between string data and numeric data. This article considers the reverse of the previous part, this time transforming numeric data into formatted strings.
Converting Numeric Values To String Data
The first part of this two part article, "C# Numeric String Conversion Part 1", described the process of converting strings into numeric data. This is particularly of use when accepting numeric input from a user. In a similar way, it is important to be able to convert numeric data to string information when outputting to screen, printer, disk or other devices. This is because much of the output functionality provided by the .NET framework requires the use of strings.
ToString Method
Every data type and class definition provided by the .NET framework includes a method named ToString. This method returns a string representation of the value or object that the method is executed against. Some classes generate objects that are not easily represented as a string and in these cases the ToString method generally returns the class' fully qualified name; that is the namespace and name together. For example:
object anObject = new object();
Console.WriteLine(anObject.ToString()); // Outputs "System.Object"
Basic Numeric Conversion Using ToString
The simplest method to convert numeric data values to strings is to use to ToString method for the data type with no parameters specified. The string produced then contains the number with no formatting applied. This method can be used on both variables and literal values.
int quantity = 1500;
float price = 1.50F;
bool sold = true;
Console.WriteLine(quantity.ToString()); // Outputs "1500"
Console.WriteLine(price.ToString()); // Outputs "1.5"
Console.WriteLine(sold.ToString()); // Outputs "True"
Formatting Converted Numbers
The basic conversion of numeric data to strings described above is useful but when displaying values to your application's user you should format the numbers appropriately for their purpose and according to the local settings of the user's environment. The ToString method permits the programmer to add format specifiers that provide this formatting. The format specifiers are supplied as a string parameter to the ToString method.
NB: The following example assumes that the code is executing on a UK machine. The results in other countries will be slightly different.
int quantity = 1500;
float price = 1.50F;
float discount = 0.05F;
Console.WriteLine(quantity.ToString("n0")); // Outputs "1,500"
Console.WriteLine(price.ToString("c")); // Outputs "£1.50"
Console.WriteLine(discount.ToString("p1")); // Outputs "5.0 %"
The three specifiers used in the above example provide fixed point notation (n), currency (c) and percentage (p) formatting. In the case of the fixed point and percentage specifier a number is included as a suffix. This is called the precision specifier and is used to modify the behaviour of the format specifier.
Available Format Specifiers
The full list of available format specifiers and the effect of the precision specifier for each is as follows:
| Specifier | Description | Effect of Precision Specifier |
|---|
| C or c | Formats the number as a monetary value including the correct number of decimal places and the appropriate currency symbol for the user's local setting | Specifies a fixed number of decimal places. | | D or d | Formats integers only as simple whole numbers. | Specifies the minimum number of digits. Leading zeroes are added if required. | | E | Formats numbers using exponential notation. The resultant string includes an upper case letter 'E'. | Specifies a fixed number of decimal places for the mantissa. If omitted, six decimal places are used. | | e | Formats numbers using exponential notation. The resultant string includes an lower case letter 'e'. | Specifies a fixed number of decimal places for the mantissa. If omitted, six decimal places are used. | | F or f | Formats numbers using fixed point notation. | Specifies a fixed number of decimal places. | | G or g | Formats numbers using either exponential or fixed point notation, whichever produces the shortest string. The actual results vary according to the data type being converted and whether a precision specifier is used. | See 'e', 'E' and 'F or f'. | | N or n | Formats numbers using fixed point notation with thousands separators. | Specifies a fixed number of decimal places. | | P or p | Formats numbers using percentage notation. For example, 0.25 is formatted as 25%. | Specifies a fixed number of decimal places. | | R or r | Formats numbers using Round-Trip Format. This is a special format that ensures that the string generated can be converted back to the original number using Parse methods. | Unused. | | X | Converts numbers into a string representation of their hexadecimal value. The digits 0 to 9 and A to F are used. | Specifies the minimum number of digits. Leading zeroes are added if required. | | x | Converts numbers into a string representation of their hexadecimal value. The digits 0 to 9 and a to f are used. | Specifies the minimum number of digits. Leading zeroes are added if required. |
Using Picture Formats for Custom Formatting
The standard format specifiers are useful in most situations, particularly when your application is being used around the world and must use the user's local settings for display of values. However, there may be some circumstances where the format specifiers do not provide the desired results. In these cases, it is possible to use a picture format. This is a format string that specifies custom formatting for numeric to string conversion.
A picture format is a string containing special characters that affect the final conversion. There are a number of available control characters; each will be considered in the following sections.
Zero Placeholder
The zero placeholder digit (0) in a custom picture format indicates that a digit is required in the resultant converted string. If there is a digit in the original number at the position of the placeholder digit then this digit is copied to the final output. If there is no digit at this position then a zero is used instead. This allows the generation of leading zeroes. If the integer part of a number being converted is longer than the number of placeholder digits then the extra digits will be included to avoid truncation. Digits following the decimal point can be rounded however.
int small = 12;
int large = 123456;
float tiny = 1.234F;
Console.WriteLine(small.ToString("0000")); // Outputs "0012"
Console.WriteLine(large.ToString("0000")); // Outputs "123456"
Console.WriteLine(tiny.ToString("0000")); // Outputs "0001"
Decimal Point Placeholder
The second special character is the decimal point placeholder. This can be combined with the zero placeholder to identify the number of digits required both before and after a decimal point. Although the decimal point placeholder character is always a full-stop or period character (.), the actual character in the resultant string is dependant upon the user's local settings. This example assumes that the user has a UK configuration:
int small = 12;
double large = 123456.789;
float tiny = 1.234F;
Console.WriteLine(small.ToString("00.00")); // Outputs "12.00"
Console.WriteLine(large.ToString("00.00")); // Outputs "123456.79"
Console.WriteLine(tiny.ToString("00.00")); // Outputs "01.23"
Digit Placeholder
The digit placeholder (#) character is similar to the zero placeholder. It defines the position of a digit within the resultant formatted string and causes rounding after the decimal point. However, the digit placeholder does not cause leading or trailing zeroes to be added to a number where the original numeric value has no digit in the appropriate position.
int small = 12;
double large = 123456.789;
float tiny = 1.234F;
Console.WriteLine(small.ToString("##.##")); // Outputs "12"
Console.WriteLine(large.ToString("##.##")); // Outputs "123456.79"
Console.WriteLine(tiny.ToString("##.##")); // Outputs "1.23"
The digit placeholder has a strange side-effect when converted a zero value to a string. As the placeholder will not cause the creation of either leading or trailing zeroes, when converting a zero value the resultant string is empty. This can be very useful in circumstances where showing zero values is not desirable.
Console.WriteLine(0.ToString("##.##")); // Outputs an empty string
Thousands Separator Placeholder
The thousands separator placeholder is represented as a comma (,). If a comma is included in the picture format to the left of any decimal point and between zero or digit placeholders then thousands separators are inserted into the resultant string. Although the thousands placeholder character is always a comma, the actual character in the resultant string is dependant upon the user's local settings. This example assumes that the user has a UK configuration:
int small = 12;
double large = 123456.789;
float tiny = 1.234F;
Console.WriteLine(small.ToString("#,#.00")); // Outputs "12.00"
Console.WriteLine(large.ToString("#,#.##")); // Outputs "123,456.79"
Console.WriteLine(tiny.ToString("#,#.##")); // Outputs "1.23"
Number Scaling Character
The number scaling character is represented as a comma (,). To differentiate between the thousands separator, the number scaling character must appear directly to the left of a decimal point or at the end of the picture format if no decimal point placeholder is present. Each number scaling character included divides the number by one thousand before applying the formatting.
int miles = 123456789;
Console.WriteLine(miles.ToString("#,#,")); // Outputs "123,457"
Console.WriteLine(miles.ToString("#,#,,.###")); // Outputs "123.457"
Console.WriteLine(miles.ToString("#,#,,")); // Outputs "123"
Percentage Placeholder
The percentage placeholder (%) is used when displaying percentage values. The placeholder performs two actions. Firstly it identifies the position in the resultant string where the percentage symbol should appear. Secondly, it multiplies the value being converted by one hundred. Although the percentage placeholder character is always a percent symbol, the actual character in the resultant string is dependant upon the user's local settings. This example assumes that the user has a UK configuration:
int small = 12;
double large = 123456.789;
float tiny = 0.0015F;
Console.WriteLine(small.ToString("#,#.#%")); // Outputs "1,200%"
Console.WriteLine(large.ToString("#,#.#%")); // Outputs "12,345,678.9%"
Console.WriteLine(tiny.ToString("#,#.#%")); // Outputs ".2%"
Custom Exponential Notation
Picture formats can be used to generate custom scientific or exponential notation. There are several characters that can be used to determine the exact exponential notation formatting used. The first character that is always required is an upper case 'E' or a lower case 'e'. This indicates that exponential notation is to be used. This is then followed by one or more zeroes to indicate the minimum number of digits to display for the exponent. The mantissa formatting is controlled by the placeholder characters that appear before the letter 'E' or 'e'.
int small = 12;
double large = 123456.789;
float tiny = 0.0015F;
Console.WriteLine(small.ToString("0.0E0")); // Outputs "1.2E1"
Console.WriteLine(large.ToString("0.00e00")); // Outputs "1.23e05"
Console.WriteLine(tiny.ToString("0.00E00")); // Outputs "1.50E-03"
The exponential notation can be modified further by adding a plus or minus symbol directly after the letter. A plus symbol (+) indicates that the sign for the exponent value should always be included in the resultant string. A minus (-) indicates that the sign character should only appear for negative exponent values.
int small = 12;
double large = 123456.789;
float tiny = 0.0015F;
Console.WriteLine(small.ToString("0.0E-0")); // Outputs "1.2E1"
Console.WriteLine(large.ToString("0.00e+00")); // Outputs "1.23e+05"
Console.WriteLine(tiny.ToString("0.00E+00")); // Outputs "1.50E-03"
Literal Characters
Often numeric values need to be formatted to include non-numeric characters. This can be achieved by inserting the characters into the picture format. To insert special characters such as those described in the previous sections, enclose them in apostrophes (') or quotes ("). For ease of reading, the following example uses apostrophes.
Console.WriteLine(12345.ToString("00-00-00")); // Outputs "01-23-45"
Console.WriteLine(12345.ToString("0'E'")); // Outputs "12345E"
Escape Characters
Escape characters may also be used in picture format strings. These use the standard backslash character to identify an escape sequence. This backslash must appear in the format string itself so must be inserted using a double-backslash if the picture format is not preceded by an '@' character. Note that to insert a backslash character into to final formatted string, four backslashes must be included in the picture format.
Console.WriteLine(123.45.ToString("\\'0.00\\'")); // Outputs "'123.45'"
Console.WriteLine(12345.ToString("000\\\\000")); // Outputs "012\345"
Section Separator Character
The final special character that can be inserted into a picture format string is the section separator. This allows different formatting to be used for positive, negative and zero values. If a single semicolon (;) character is included in the custom format string then the format to the left of the semicolon is used for positive values and the format to the right for negative numbers. Adding a second section separator indicates that the third section is to be applied to zero values. If the second section is omitted by having no characters between the two semicolons then the positive and negative formats will both use the formatting from the first section.
Console.WriteLine(1.ToString("0.0;(0.0)")); // Outputs "1.0"
Console.WriteLine((-1).ToString("0.0;(0.0)")); // Outputs "(1.0)"
Console.WriteLine(1.ToString("0.0;(0.0);#.#")); // Outputs "1.0"
Console.WriteLine((-1).ToString("0.0;(0.0);#.#")); // Outputs "(1.0)"
Console.WriteLine(0.ToString("0.0;(0.0);#.#")); // Outputs an empty string
Console.WriteLine(1.ToString("0.0;;#.#")); // Outputs "1.0"
Console.WriteLine((-1).ToString("0.0;;#.#")); // Outputs "-1.0"
Console.WriteLine(0.ToString("0.0;;#.#")); // Outputs an empty string
|