How do I write out a curly bracket in string formats?

Largly modivated by your comments on a recent post, Kit George recently posted a FAQ on string formatting on the BCL Website

A couple of interesting items below… or suggest your own.


How do I write out a curly bracket in string formats?
In order to print out a curly bracket in a string using string formatting, simply put two of the curly brackets in a row. This is referred to as ‘escaping’ the curly bracket.

string s = String.Format(“{{ hello to all }}”);
Console.WriteLine(s);    //prints ‘{ hello to all }’



Do escaped curly brackets have any odd behaviors I need to be aware of?
There is an interesting result from the decision to use two curly brackets in order to print a single curly bracket in a format string.
If you want to actually use the standard ability to use a referenced parameter in string formatting, you might write this kind of code:

int i = 42;
string s = String.Format(“{0}”, i);   //prints ’42’


However, what if I want to print out ‘{42}’? It would seem that this line of code is fairly intuitive, based on my attempt to escape the curly brackets:

int i = 42;
string s = String.Format(“{{{0}}}”, i);   //prints ‘{42}’

Now however, I want to take advantage of some of the more robust formatting options available, and specify a format for the variable. I want to print it out in Number format, using the N specifier:

int i = 42;
string s = String.Format(“{0:N}”, i);   //prints ‘42.00’

Going a step further, I want to print out my value with curly brackets around it, using the Number format specifier. So, I expected this to work:

int i = 42;
string s = String.Format(“{{{0:N}}}”, i);   //prints ‘{N}’

The question is, why did this last attempt fail? There’s two things you need to know in order to understand this result:

  1. When providing a format specifier, string formatting takes these steps:
    • Determine if the specifier is longer than a single character: if so, then assume that the specifier is a custom format. A custom format will use suitable replacements for your format, but if it doesn’t know what to do with some character, it will simply write it out as a literalliterals found in the format
    • Determine if the single character specifier is a supported specifier (such as ‘N’ for number formatting). If it is, then format appropriately. If not, throw an ArgumnetException
  2. When attempting to determine whether a curly bracket should be escaped, the curly brackets are simply treated in the order they are received. Therefore, “{{{” will escape the first two characters and print the literal ‘{‘, and the the third curly bracket will begin the formatting section. On this basis, in “}}}” the first two curly brackets will be escaped, therefore a literal ‘}’ will be written to the format string, and then the last curly bracket will be assumed to be ending a formatting section

With this information, we now can figure out what’s occurring in our “{{{0:N}}}” situation. The first two curly brackets are escaped, and then we have a formatting section. However, we then also escape the closing curly bracket, before closing the formatting section. Therefore, our formatting section is actually interpreted as containing “0:N}”.

Now, the formatter looks at the format specifier and it sees “N}” for the specifier. It therefore interprets this as a custom format, and since neither N or } mean anything for a custom numeric format, these characters are simply written out, rather than the value of the variable referenced.

This last bit gets a little confusing, but it becomes clearer if we compare this behavior with something like the following:

int i = 42;
string s = String.Format(“{0:N!}”, i);   //prints ‘N!’

The same thing occurs in this situation, but it’s a little clearer, because we don’t have any escaping. Basically, the format specifier is seen as “N!”, which gets interpreted as a custom format (longer than one character), and because the custom format has nothing special to do with numbers, then N! is simply used for the value.


Passing structures between C# and C/C++


Data structures can be passed between managed C# code and unmanaged C/C++ dynamic link libraries but it can be a little complicated. The trick is to define structures that match between the two different languages; and perhaps write wrapper functions that hide away the complexity of the memory marshaling code. I will show a couple of simple examples of passing a system time data structure from C/C++ to C# and vice versa here.

The C/C++ definition of the system time structure is as follows:

typedef struct _SYSTEMTIME {
    WORD wYear;
    WORD wMonth;
    WORD wDayOfWeek;
    WORD wDay;
    WORD wHour;
    WORD wMinute;
    WORD wSecond;
    WORD wMilliseconds;

The matching C# equivalent of the system time structure can be defined as shown below.

private struct SYSTEMTIME
    public UInt16 wYear;
    public UInt16 wMonth;
    public UInt16 wDayOfWeek;
    public UInt16 wDay;
    public UInt16 wHour;
    public UInt16 wMinute;
    public UInt16 wSecond;
    public UInt16 wMilliseconds;

Example 1: Passing a structure from C/C++ to C#
If the C/C++ function has the following signature:

HRESULT GetDateTime( HANDLE hClient, SYSTEMTIME* pSysTime );

Then the following wrapper functions can be used to call the C/C++ function.

private static extern int GetDateTime(IntPtr hClient, IntPtr pSysTime);
public static int GetDateTime(IntPtr hClient, out DateTime sysTime)
    int hr = 0;
    IntPtr pSysTime = IntPtr.Zero;
    SYSTEMTIME theTime = new SYSTEMTIME();
    sysTime = new DateTime();
    pSysTime = Marshal.AllocHGlobal( Marshal.SizeOf(theTime));
    hr = GetDateTime(hClient, pSysTime);
    theTime = (SYSTEMTIME) Marshal.PtrToStructure(pSysTime, typeof(SYSTEMTIME));
    sysTime = new DateTime(theTime.wYear, theTime.wMonth, theTime.wDay, theTime.wHour, theTime.wMinute, theTime.wSecond, theTime.wMilliseconds);
    return hr;

To use the wrapper functions, simply do something like the following:

IntPtr hClient = IntPtr.Zero;
DateTime dt = new DateTime();
int ret = GetDateTime( hClient, out dt);

Example 2: Passing a structure from C# to C/C++
If the C/C++ function has the following signature,

HRESULT SetDateTime( HANDLE hClient, SYSTEMTIME* pSysTime );

Then the following wrapper functions can be used to call the C/C++ function.

private static extern int SetDateTime(IntPtr hClient, IntPtr pSysTime);
public static int SetDateTime(IntPtr hClient, DateTime sysTime)
    int hr = 0;
    IntPtr pSysTime = IntPtr.Zero;
    SYSTEMTIME theTime = new SYSTEMTIME();
    theTime.wYear = (ushort) sysTime.Year;
    theTime.wMonth = (ushort) sysTime.Month;
    theTime.wDay = (ushort) sysTime.Day;
    theTime.wDayOfWeek = (ushort) sysTime.DayOfWeek;
    theTime.wHour = (ushort) sysTime.Hour;
    theTime.wMinute = (ushort) sysTime.Minute;
    theTime.wSecond = (ushort) sysTime.Second;
    theTime.wMilliseconds = (ushort) sysTime.Millisecond;
    pSysTime = Marshal.AllocHGlobal(Marshal.SizeOf(theTime));
    hr = SetDateTime(hClient, pSysTime);
    return hr;

Do the following to call the wrapper functions.

DateTime dt = new DateTime();
int hr = SetDateTime(hClient, dt);