Home About

February 4th, 2009

Formatting Strings in C# with String.Format - 2

A String.Format Reference for C#

String.Format is a very powerful method but the documentation at MSDN is quite wordy and spreads the details over many pages. For this post I have made quick reference to its many specifiers and for good measure added some examples to help get you started.If you would like to format a date, currency, number or just the time, String.Format is your friend.

For a trip down memory lane a little example how we did things in C. The C sprintf function takes a buffer, a formatting string, a couple of parameters and munches them together:

#include <stdio.h>
int main()
{
char buffer[255];
sprintf(buffer,"Customer %d lives is %d years old and owns us %2.2f dollars", 1024, 96, 125.6f);
printf("%s",buffer);
}

This results in the following output:

Customer 1024 is 96 years old and owns us 125.50

Of course, if we made the buffer too small and the string expanded too much we might have created a buffer overrun once of C’s pesky little annoyances. And of course for each parameter we need to specify how to format them (%d for integers, %s for strings and %f for floats). Get the type wrong and things will go funny fast.

Enter String.Format and Console.WriteLine

So how do things work in C#? The String.Format method takes care of all our needs and a little more. Similar to the relationships between sprintf and printf the methods String.Format and Console.WriteLine work similary. String.Format returns a string whereas Console.WriteLine sends the resulting string to the console output.

The following should be a familiar example:

int ResultValue = 123;
string myString = String.Format(“The value is {0}”,ResultValue);
Console.WriteLine(“The value is {0}”,ResultValue);

The Index

The {0} is an index and refers to the first parameter given following the formatting string. {1},{2} to the second, third etc. You can also refer to a parameter more than once. The following is perfectly acceptable:

Console.WriteLine(“First {0}, Second {1}, Third {2}, And again the First {0}”,Value1,Value2,Value2);

Aligning the output

C# provides an alignment value that allows you to left or right align the output. Handy for screen or print formatting.

If you specify an alignment of 10 characters the resulting string will always be 10 characters even if the number only took up 4 places. The remainder is padded with spaces. If the value we want to display is longer than our given alignment size the alignment value is ignored.

Console.WriteLine(“The value is {0,10} – continue from here”,9999);

The above will output the value “9999″, and allocate 10 spaces for it. The output is right-aligned, the format method will simply add sufficient spaces to make sure the total length adds up to 10 characters.

To make the output left-aligned we need to make the number negative:

Console.WriteLine(“The value is {0,-10} – continue from here”,9999);

Displaying enumerated types

One very interesting feature of C# is the ability to display enumerated types.If you make your own enumeration wouldn’t it be nice if you could just print the values as a string literals? In fact you can as shown by the following example:

class MainClass
{
public enum Transport {Car = 1, Plane = 2, Motorcycle = 3}

public static void Main(string[] args)
{
Transport peopleMover = Transport.Plane;

Console.WriteLine("{0:G}",peopleMover);  // string literal
Console.WriteLine("{0:f}",peopleMover);   // flag -- not clear
Console.WriteLine("{0:d}",peopleMover);  // decimal
Console.WriteLine("{0:x}",peopleMover);   // hexadecimal
}
}

This outputs:

Plane

Plane

2
00000002

Basic number formatting

When no format is specified the String.Format method applies the “g” (General) type, which results in any value passed being rendered into a standard string. The following table shows what is possible:

If the table lists (error) it means that the String.Format method threw a String.Formatting exception. This happens if the number cannot be converted properly.

Format specifier Name 1234.56 (double) -100000 (int) Description
{0:c} Currency $123.45 ($-100,000.00) The number is converted to a string that represents a currency amount.
{0:d} Decimal (error) -100000 Display a decimal amount, but throws an exception on non-decimal values (floats).
{0:e} Scientific 1.234500e+002 -1.000000e+005 The number is converted to a string of the form “-d.ddd…E+ddd” or “-d.ddd…e+ddd”, where each ‘d’ indicates a digit (0-9).
{0:f} Fixed-point 123.45 -100000.00 The number is converted to a string of the form “-ddd.ddd…” where each ‘d’ indicates a digit (0-9). The string starts with a minus sign if the number is negative.
{0:g} General 123.45 -100000 The default format
{0:n} Number 123.45 -100,000.00 Thousand separators are inserted between each group of three digits to the left of the decimal point.
{0:p} Percent 12,345.00% -10,000,000.00 % The number is converted to a percentage.
{0:r} Round-Trip 123.45 (error) Guarantees that the number can be returned to its original value on conversion from string to number.
{0:x} or {0:X} Hexadecimal (error) FFFE7960 Use ‘X’ to produce “ABCDEF”, and ‘x’ to produce “abcdef”.

Custom number formatting

Of course, your preferred format is not listed above and you need a few modifications made. Not a problem. Custom formatting allows for any kind of number-to-string conversion you might need:

Name Format Example Input Output
Zero placeholder 0 {0:000.00} 45.5 045.50
Digit placeholder # {0:###.##} 45.5 45.5
Decimal point . {0:00.00} 45.5 45.50
Thousand separator (requires 0) , {0:0,0} 1000000 1,000,000
Percent (multiplies by 100) % {0:0%} 45.5 4550%
Scientific notation (multiple formats) E0,E+0,E-0,e0,e+0,e-0 {0:E0} 1000000 1E+006

Date formats

The following table show the basic date formats obtained from calling DateTime.Now and then formatting the result. Note that different systems might produce different results depending on how the operating system is configured (think Chinese/Japanese/etc systems).

Specifier Description Example
{0:d} Short date 2/4/2009
{0:D} Long date Wednesday, February 04, 2009
{0:t} Short time 2:59 PM
{0:T} Long time 2:59:14 PM
{0:f} Full date/time (short time) Wednesday, February 04, 2009 2:59 PM
{0:F} Full date/time (long time) Wednesday, February 04, 2009 2:59:40 PM
{0:g} General date/time (short time) 2/4/2009 2:59 PM
{0:G} General date/time (long time) 2/4/2009 3:01:12 PM
{0:M} Month day February 4
{0:R} RFC1123 Wed, 04 Feb 2009 15:01:55 GMT
{0:s} Sortable date/time ; conforms to ISO 8601 2009-02-04T15:02:10
{0:u} Universal sortable date/time 2009-02-04 15:02:28Z
{0:U} Universal sortable date/time Wednesday, February 04, 2009 7:03:11 AM
{0:Y} Year month February, 2009


Custom Date formatting

The custom format strings allow DateTime objects to be formatted when the standard formatting strings are not useful and you need some special.

Specifier
Description
Example
Output
d Day of the month as a number {0:d} 4
dd Day of the month as a number, with leading zero {0:dd} 04
ddd Abbriviated day of the month name {0:ddd} Wed
dddd Full day of the month name {0:dddd} Wednesday
f,ff,fff Fraction of a second (repeat “f” for more precision) {0:fff} 405
gg,ggg The era {0:gg} A.D.
h Hour (1-12 range) {0:h} 3
hh Hour (1-12 range, with leading zero for 0-9) {0:hh} 03
H Hour (0-23 range) {0:H} 15
HH Hour (0-23 range with leading zero for 0-9) {0:HH} 03
m Minutes (0-59) {0:m} 9
mm Minutes (0-59 range with leading zero for 0-9) {0:mm} 09
M Number of the month (0-12) {0:M} 2
MM Number of the month (0-12 with leading zero for 0-9) {0:MM} 02
MMM Abbreviated name of the month {0:MMM} Feb
MMMM Specifies the full name of the month {0:MMMM} February
s Seconds (0-59 range) {0:s} 23
ss Seconds (0-59 range with leading zero for 0-9) {0:ss} 23
tt Both characters of the AM/PM range {0:tt} PM
y The first two digits of the year (0-99) {0:y} 9
yy The first two digits of the year (0-99) with leading zero for 0-9 {0:yy} 09
yyyy Four digit year number, if the year is less than 1000 it has 0′s prepended {0:yyyy}
zz The timezone offset in whole hours {0:zz} +08
zzz The timezone offset in hours and minutes {0:zzz} +08:00
: Time seperator {0:hh:mm} 03:33
/ Date seperator {0:MM/yyyy} 02/2009

Image credit: easement

Be Sociable, Share!

Tags: ,

2 Responses to “Formatting Strings in C# with String.Format”

  1. Henk Says:

    Hi,

    What happened to the word “lives” in the first example?

    sprintf(buffer,”Customer %d lives is %d years old and owns us %2.2f dollars”, 1024, 96, 125.6f);
    Customer 1024 is 96 years old and owns us 125.50

  2. String.Format | selcukterzi Says:

    [...] Quote:http://www.dijksterhuis.org/formatting-strings-stringformat/ [...]


Most popular

    Sorry. No data so far.

Recent Comments
  • Juan Romero: Hi there, it’s a neat little class, but I believe you could do the same thing with the WebClient...
  • anthosh: Hey, THank you very much for your tutorial. It was awesome. But i have a problem that i am not able to...
  • bian: how to get passphase if i have encrypt and decrypt string?? Thanks alot
  • Michael: Hi, I really like your post, thanks a lot, it really helped clear up a few things I could not remember how...
  • Bharat Prajapati: i was trying to import keyword dictionary to this plugin which is in csv format, but i get an error...