Feb 8 2006

String Formatting in C#

Category:Bil@l @ 07:45

String Formatting in C#

I couldn’t find a quick reference to .NET string formatting using the String.Format() function, so I created this one.

When I started working with the .NET framework, one thing puzzled me. I couldn’t find sprintf(). sprintf() is the C function that takes an output buffer, a format string, and any number of arguments, and builds a string for you. For example:

char szError[256];
sprintf(szError, “Error %d occurred.\n”, nError);

This would write “Error 12 occurred.” into the szError buffer (assuming nError was 12). It’s a basic part of C programming and most C++ programmers still use it though better functionality is available in the STL because sprintf is simple to use and clear. The STL equivalent would be:

str << “Error ” << nError << ” occurred.” << endl;

Or something close to that. It’s type-safe, and more OO than sprintf, but not as easy to read and not as easy to localize.

The .NET framework handles strings very nicely - but it takes some getting used to. The rough equivalent of sprintf in .NET is the static String.Format function, which takes a format string and some arguments, and generates an output string. (This is a nice improvement over sprintf since there’s no chance you’ll overflow the output buffer). For example:

string errorString = String.Format(”Error {0} occurred.”, nError);

Teeming with metadata, the .NET environment doesn’t need the format string to say what type of data you’re formatting, just where you want it. (A common sprintf bug is supplying the wrong data type - there’s no protection from using %s instead of %d and having your program crash when sprintf is called).

The {0} in the string above is replaced with the value of nError, but what if you want to specify the number of digits to use? Or the base (hexadecimal etc)? The framework supports all this, but where it seemed confusing is that it’s not the String.Format function that does the string formatting, but rather the types themselves.

Every object has a method called ToString that returns a string representation of the object. The ToString method can accept a string parameter, which tells the object how to format itself - in the String.Format call, the formatting string is passed after the position, for example, “{0:##}”

The text inside the curly braces is {index[,alignment][:formatString]}. If alignment is positive, the text is right-aligned in a field the given number of spaces; if it’s negative, it’s left-aligned.


There really isn’t any formatting within a strong, beyond it’s alignment. Alignment works for any argument being printed in a String.Format call.

Sample Generates
String.Format(”->{1,10}<-”, “Hello”); -> Hello<-
String.Format(”->{1,-10}<-”, “Hello”); ->Hello <-


Basic number formatting specifiers:

Specifier Type Format Output (Passed Double 1.42) Output (Passed Int -12400)
c Currency {0:c} $1.42 -$12,400
d Decimal (Whole number) {0:d} System.FormatException -12400
e Scientific {0:e} 1.420000e+000 -1.240000e+004
f Fixed point {0:f} 1.42 -12400.00
g General {0:g} 1.42 -12400
n Number with commas for thousands {0:n} 1.42 -12,400
r Round trippable {0:r} 1.42 System.FormatException
x Hexadecimal {0:x4} System.FormatException cf90

Custom number formatting:

Specifier Type Example Output (Passed Double 1500.42) Note
0 Zero placeholder {0:00.0000} 1500.4200 Pads with zeroes.
# Digit placeholder {0:(#).##} (1500).42
. Decimal point {0:0.0} 1500.4
, Thousand separator {0:0,0} 1,500 Must be between two zeroes.
,. Number scaling {0:0,.} 2 Comma adjacent to Period scales by 1000.
% Percent {0:0%} 150042% Multiplies by 100, adds % sign.
e Exponent placeholder {0:00e+0} 15e+2 Many exponent formats available.
; Group separator see below

The group separator is especially useful for formatting currency values which require that negative values be enclosed in parentheses. This currency formatting example at the bottom of this document makes it obvious:


Note that date formatting is especially dependant on the system’s regional settings; the example strings here are from my local locale.

Specifier Type Example (Passed System.DateTime.Now)
d Short date 10/12/2002
D Long date December 10, 2002
t Short time 10:11 PM
T Long time 10:11:29 PM
f Full date & time December 10, 2002 10:11 PM
F Full date & time (long) December 10, 2002 10:11:29 PM
g Default date & time 10/12/2002 10:11 PM
G Default date & time (long) 10/12/2002 10:11:29 PM
M Month day pattern December 10
r RFC1123 date string Tue, 10 Dec 2002 22:11:29 GMT
s Sortable date string 2002-12-10T22:11:29
u Universal sortable, local time 2002-12-10 22:13:50Z
U Universal sortable, GMT December 11, 2002 3:13:50 AM
Y Year month pattern December, 2002

The ‘U’ specifier seems broken; that string certainly isn’t sortable.

Custom date formatting:

Specifier Type Example Example Output
dd Day {0:dd} 10
ddd Day name {0:ddd} Tue
dddd Full day name {0:dddd} Tuesday
f, ff, … Second fractions {0:fff} 932
gg, … Era {0:gg} A.D.
hh 2 digit hour {0:hh} 10
HH 2 digit hour, 24hr format {0:HH} 22
mm Minute 00-59 {0:mm} 38
MM Month 01-12 {0:MM} 12
MMM Month abbreviation {0:MMM} Dec
MMMM Full month name {0:MMMM} December
ss Seconds 00-59 {0:ss} 46
tt AM or PM {0:tt} PM
yy Year, 2 digits {0:yy} 02
yyyy Year {0:yyyy} 2002
zz Timezone offset, 2 digits {0:zz} -05
zzz Full timezone offset {0:zzz} -05:00
: Separator {0:hh:mm:ss} 10:43:20
/ Separator {0:dd/MM/yyyy} 10/12/2002


Specifier Type
g Default (Flag names if available, otherwise decimal)
f Flags always
d Integer always
x Eight digit hex.

Some Useful Examples

String.Format(”{0:$#,##0.00;($#,##0.00);Zero}”, value);

This will output “$1,240.00? if passed 1243.50. It will output the same format but in parentheses if the number is negative, and will output the string “Zero” if the number is zero.

String.Format(”{0:(###) ###-####}”, 8005551212);

This will output “(800) 555-1212?.

If you have any questions about string formatting, or pretty much anything related, drop by the Forum and ask it there. It’s an easier place to talk than in the comments section here.

14 Responses to “String Formatting in C#”

  1. stevex » Blog Archive » Different Theme Says:

    […] In case anyone reads this on the main page instead of in an aggregator.. I’m trying out a different theme. It’s wider, so code snippets don’t wrap. I wanted to make my String Formatting in C# page look good since searching for how to do sprintf type formatting in C# is how most people find this site. […]

  2. pwalls Says:

    Great resource! This is definitely a handy reference page I’ve added to my favorites. However, I did notice a minor error.

    The following:

    String.Format(”{0:(###) ###-####}”, 18005551212);

    Produces (1800) 555-1212 and not (800) 555-1212.

    Otherwise, great information.

  3. Tim Lewis Says:

    This will output “$1,240.00? if passed 1243.50. It will output the same format but in parentheses if the number is negative, and will output the string “Zero” if the number is zero.

    String.Format(”{0:$#,##0.00;($#,##0.00);Zero}”, 1243.50); // Outputs “$1,243.50? not the claimed “$1,240.00?

  4. Max Says:

    I want format String



  5. murugan.g Says:

    Hi Steve,

    Thanks for this wonderful article.

    How can i format date like this “December 08th, 2005?.

  6. Jorge de Cardenas Says:

    Someone asked if 0,1 could be formatted to no,yes on your other page

    this can be done with formatting using:

    String.Format(”{0:yes;;no}”, value)

    => yes if value == 1
    => no if value == 0

  7. Jeremy Says:

    Was this article ripped off from here:



    I ask because they are almost identical.

  8. stevex Says:

    Nope.. it looks like they’re just surprisingly coincidentally similar. My original article was posted in 2003, over here:


    His was posted 2004.

  9. Krise Says:

    Nice howto,
    there is a small error in it though:

    the following :

    Sample Generates
    String.Format(”->{1,10} Hello{1,-10}Hello

  10. Broads Says:


    I have found this blog very usefull but was wondering if you may shed some light on the following.
    I have a shopping basket on my site which should display my total as GBP £x.xx however when using the string.format {0:c} the currency of the hosting server is used. So when I developed and tested my site all looked fine. When I then hosted my site it took, i presume, the localisation of the hosts server and displayed as $x.xx

    To get around this I am now using string.format{0:#.##} which is then prefixed with a physical £ sign.

    Is this the correct way to get over this formating issue or is there a better way.


  11. Philippe Quesnel Says:

    great info ! at last, I always swear at the .NET doc when looking form string formatting info ;-)

    note: the 1st example, right at the top of the article:
    String.Format(”->{1,10} Hello{1,-10}Hello

  12. Philippe Quesnel Says:

    oops, sorry, don’t know what happened to my text in the 1st post !! ??

    here it is again, hopefully complete this time !

    great info ! at last, I always swear at the .NET doc when looking form string formatting info ;-)

    note: the 1st example, right at the top of the article:
    String.Format(”->{1,10} Hello{1,-10}Hello

  13. tom callaghan Says:

    I know there is a way to do this, I just cannot remember the format string. I want to force a sign place holder so that either ‘+’ for positive numbers or ‘-’ for negative numbers will print. For example

    34.2 outputs as +34.2 and -34.2 outputs as -34.2

  14. ddegenaro Says:

    if i have converted from like “1110.20? to “$1,110.20? using {0:C}
    how do i convert “$1,110.20? back to “1110.20?..i tried {0:f} and {0:0.00}
    still doesnt work!


Feb 3 2006

Windows WorkFlow

Category:Bil@l @ 20:49

Yesterday the LebDev.NET user group in Lebanon offered a great session about

Working with Windows WorkFlow.

As part of the Community Nights, sponsored by Microsoft Beirut Office and held by the LebDev.NET user group.

For more information on Windows WorkFlow, make sure to check the links below:







Jan 31 2006

Convert UserControls to Custom Controls

Category: ASP.NET 2.0 - GeneralBil@l @ 21:40

I found a nice article today on MSDN titled as:
Turning an .ascx User Control into a Redistributable Custom Control

I will summarize as much as possible of that article, since it is really a valuable one.

It talks about creating your own UserControls, then converting them into CustomControls.

Create a New Web Site in Visual Studio 2005 (I guess it should work in VWD too, haven't tried it). Name it WebUserControl (Namespace Name!!!)

  • Add a new Web User Control
  • Design the control the way you want. For the same of this post, I created this simple user control shown below, you can use either Code-Beside or Code-Inline:
<%@ Control Language="C#" ClassName="WebUserControl.HelloWorld" %>

<script runat="server">

    protected void btnSubmit_Click(object sender, EventArgs e)
        this.lblMsg.Text = Server.HtmlEncode(this.txtMsg.Text);

<strong>Hello World Custom-User Control<br />
<br />
Enter Your Name:
<asp:TextBox ID="txtMsg" runat="server"></asp:TextBox>
<asp:Button ID="btnSubmit" runat="server" OnClick="btnSubmit_Click" Text="Submit" /><br />
<br />
<br />
<asp:Label ID="lblMsg" runat="server"></asp:Label>
  • Compile the control, and then add it to the default.aspx page that came with the website upon its creation. Make sure it works, and then delete that default.aspx page.
  • Now we need to publish the usercontrol, why? In ASP.NET 2.0, every aspx page or ascx file, will be converted to its own DLL file either through precompiling or at run time. In this example, we will publish the website, which requires precompiling the website, and this generating the DLL that resembles the user control under test.
    • Go to Build --> Publish Web Site
    • Type in the Target Location, where the precompiled files shall be placed.
    • Deselect the *Allow this precompiled to be updatable*, why? In the updatable mode, only the code-beside will be precompiled and not the ascx file itself. In our case we need both to be in one DLL.
    • Select *Use fixed naming and single page assemblies*. "This will gurantee that your user control will be compiled into a single assembly that will have a name based on the ascx file itself ..."
  • Now, the user control is precompiled. Create a new website, right click the application, Add Reference, choose the DLL just created.
  • On an aspx page, ad the following below the page directive:
<%@Register TagPrefix="bhaidar" Namespace="WebUserControl" Assembly="App_Web_helloworld.ascx.cdcab7d2"%>

The Namespace is the same as the Namespace in which the UserControl was created.
The Assembly, is the name of the DLL file generated

  • Inside the page body, add the following control:
<bhaidar:helloworld id="MyUC" runat="server"/>

Although this method made your user controls become custom controls yet, the custom controls won't have any desing time view and this is really a loss!!!

Hope you enjoyed this post and found it beneficial.





Jan 31 2006

Download Visual Studio 2005 Code Snippets

Category: ASP.NET 2.0 - GeneralBil@l @ 21:34

You can now download a set of Code Snippets to use in your C# development.

Please check this link for more information: Visual Studio 2005 Code Snippets





Jan 31 2006

LebDev.NET UserGroup - Next Community Night - Thursday, February 2 - 2006

Category:Bil@l @ 18:33

I would like to invite, all those who are capable of attend, to the 8th Session out of the series of the Community Nights held by Microsoft Beirut Offices and the LebDev.NET UserGroup, which is the first Lebanese UserGroup.

The topic of this coming session is:  Introduction to Windows Workflow Foundation

The session will be presented by:
Mr. Tarek Bohsali, Senior Consultant, Microsoft Consulting Services.

To have more information on this session, please visit our user group website at:



Hope to see you all,

LebDev WebMaster


Jan 30 2006

Extend String.IndexOf() &amp; String.LastIndexOf() Methods

Category:Bil@l @ 09:31

I have always found a limitation in the string.IndexOf() and string.LastIndexOf() methods in a sense that, you can either get the position of the first occurrence or the last occurence of a certain value within a given string.

What if we want to get the position of a value at the second occurrence or third or fourth, etc ...?

The solution is simple, look at the following C# function:

public int PositionOf(string strString, string value, int occurrence)
    int num1 = -1;

    for(int i=0; i<occurrence; i++)
        num1 = strString.IndexOf(value,num1+1);

    return (num1);

What this simple function does, is to return the position of a value within a given string at any occurrence of choice.

A great thanks to my colleague Ms. Samar Khayat who shared her ideas while working on this function in our office work.




Jan 27 2006

Add a Custom Link in CS 2.0 Beta 3

Category:Bil@l @ 16:37

In reference to a post on the http://www.communityserver.org forums, on how to create a custom section in CS 2.0 beta 3, I decided to write this post here.

1- Open SiteUrls.config, in the Locations section, add the following no matter where you places them preferably before the weblogs location.:

     <location name="CustomPage" path="/CustomSection/" exclude="true" />

2- In the Navigation section, add the following according to your own order you want:

      <link name="CustomPage" text ="Custom Link" navigateUrl="/cs/CustomSection" />

You must be aware that I have installed CS on http://localhost/cs

3- Create a new folder called CustomSection inside the web folder.

4- Add a page called default.aspx page.

5- Now you want to show some content on the page right? You need to follow a certain Master usercontrol. Go to /Themes/default/Masters/ create a new text file name it CustomPage.ascx.

6- Open the HomeMaster.ascx usercontrol, copy its content and paste them in the new CustomPage.ascx.

6- Make sure you change the following line in the CustomPage.ascx:

<CS:SelectedNavigation Selected = "Home" runat="Server" id="Selectednavigation1" />

Make sure you remove the word Home and replace it with the name of the custom location in SiteUrls.config, and in this case, rename it to: CustomPage. This is done so that, once you are in the Custom Section, its link will be highlighed to differentiate where you are now.

7- Now that you created the Master control, you need to open the default.aspx page in the root folder i.e. (/cs/default.aspx), copy its content and paste it in the default page inside (/cs/CustomSection). You can use the code below to show all the different available sections inside a page, that you can have, at least that is what I was able to find out.

<%@ Page SmartNavigation="False" Language="C#"  enableViewState = "false" %>
<%@ Register TagPrefix="CSD" Namespace="CommunityServer.Discussions.Controls" Assembly="CommunityServer.Discussions" %>
<%@ Register TagPrefix="CS" Namespace="CommunityServer.Controls" Assembly="CommunityServer.Controls" %>
<%@ Register TagPrefix="Galleries" Namespace="CommunityServer.Galleries.Controls" Assembly="CommunityServer.Galleries" %>
<%@ Register TagPrefix="Blog" Namespace="CommunityServer.Blogs.Controls" Assembly="CommunityServer.Blogs" %>
<%@ Import Namespace="CommunityServer.Components" %>
<%@ Import Namespace="CommunityServer.Discussions.Components" %>
<%@ Import Namespace="CommunityServer.Blogs.Components" %>
<%@ Import Namespace="CommunityServer.Galleries.Components" %>

<CS:MPContainer runat="server" id="Mpcontainer1" ThemeMasterFile = "CustomMaster.ascx" >

 <CS:MPContent id="lcr" runat="server" >
  <div class="CommonSidebar">
   <cs:ContentPart runat = "Server" contentname="featuredLCP" id = "featuredContentPartLCP">
    <div class="CommonSidebarArea">
     <h4 class="CommonSidebarHeader">Left Area
     <div class="CommonSidebarContent">
      <p>You Place the Left Side content here!!</p>

 <CS:MPContent id="bcr" runat="server">
  <div class="CommonContentArea">
   <div class="CommonContent">
   <cs:ContentPart runat = "Server" contentname="welcomeBCP" id = "welcomeContentPartBCP"
      text="<h2 class='CommonTitle'>Welcome to Community Server! </h2><IMG src='http://communityserver.org/utility/images/showcase_sites.gif' align=right> <a href='http://communityserver.org/r.ashx?3' target='_blank'>Community Server</a> is the award winning platform that enables you to quickly and easily create online communities. <p>Community Server is a collaboration platform and includes: discussions, blogs, content management, photo gallery, file gallery, user management tools, advanced permissions system, extensible theme engine, and much more.</p><p>Community Server is a shared source platform developed, maintained, supported-by, and licensed by <a href='http://communityserver.org/r.ashx?2' target='_blank'>Telligent</a>. Telligent additionally offers services for helping customize, host, and manage your Community Server system.</p>" />

 <CS:MPContent id="rcr" runat="server" >
  <div class="CommonSidebar">
   <cs:ContentPart runat = "Server" contentname="featuredRCP" id = "featuredContentPartRCP">
    <div class="CommonSidebarArea">
     <h4 class="CommonSidebarHeader">Right Area
     <div class="CommonSidebarContent">
      <p>You Place the Right Side content here!!</p>
 <CS:MPContent id="BodyFooterRegion" runat="server" >
  <div class="CommonSidebar">
   <cs:ContentPart runat = "Server" contentname="featuredFCP" id = "featuredContentPartFCP">
    <div class="CommonSidebarArea">
     <h4 class="CommonSidebarHeader">Footer Area</h4>
     <div class="CommonSidebarContent">
      <p>You Place the Footer content here!!</p>

At least this will show you a page similar to the one here.

Hope this helps you out. I am always ready for any comment or question. Above all, if you guys from CS team find anything wrong, or anything can be improved in my post to make creating custom sections in CS esay, please do comment or contact me directly.

Thank you all,
A special thanks to Scott Watermasysk



Jan 27 2006

Upgraded my website to CS 2.0 Beta 3

Category: General | GeneralBil@l @ 11:01

I have just finished upgrading my website to CS 2.0 Beta 3.

I have also played around a bit with CS files and created a Custom Link, to show how easy it is to work with a CS website.

Although it is not yet a CMS, however, it could be used now for a community site very easily, specially that adding new links and sections is not a tough thing to do.

Hope you enjoy the stay,



Tags: ,

Jan 25 2006

How to publish Community Server 1.1 remotely?

Category: Community ServerBil@l @ 10:21

In a previous post, we have seen how to install CS 1.1 on a local machine.

Now it is time to upload our installation to our own web space. We will be installing CS 1.1 inside a folder called *cs*, so now you can have the CS 1.1 home page @: http://mywebsite.com/cs/

  • Copy the web folder where you had your CS 1.1 installation on your local machine, suppose it is called *Web*, to the root of your web space
  • Create a Virtual Directory called cs that points to the folder called Web thay you just have uploaded to your root directory of the web space
  • Make sure the database has been upload successfully, how to upload it? Depends on the hosting company you are working with
  • Open the table called cs_Sites, you will find inside it a record that has a SiteUrl of *localhost/cs*, change this to something as *mywebsite.com/cs*

That is all, you have now a working version of the CS 1.1 on your web space.





Jan 24 2006

Community Server 2.0 Beta 3 is in town !!!

Category:Bil@l @ 21:54

You can now download the CS 2.0 Beta 3 as:

Windows and Web Installers.