Back to Home

string.Format in C# — Syntax, Format Specifiers, and Examples

string.Format composes a string by replacing numbered placeholders ({0}, {1}, …) with supplied values. If you are looking for a practical answer to "string.format c#", the short version is that it is useful when you want a reusable format template, especially for localization or external configuration.

It has been superseded by string interpolation in most inline scenarios, but it remains a strong choice when the format string is stored externally or when you need to reuse a template.

Every Console.WriteLine call that accepts a format string uses the same composite formatting rules internally.

Basic Syntax

C# Example Code
// {index} — positional placeholder
string result = string.Format("Hello, {0}! You have {1} messages.", "Alice", 5);
Console.WriteLine(result);
// Hello, Alice! You have 5 messages.

// Reuse the same argument multiple times
string repeated = string.Format("{0} + {0} = {1}", 7, 14);
Console.WriteLine(repeated);
// 7 + 7 = 14

// Pass a params array
object[] args = { "Bob", 42 };
Console.WriteLine(string.Format("Name: {0}, Age: {1}", args));
// Name: Bob, Age: 42

Numeric Format Specifiers

C# Example Code
double amount  = 12345.6789;
int    count   = 42;
double ratio   = 0.1875;
int    hex     = 255;

// C — currency (uses current culture)
Console.WriteLine(string.Format("{0:C}",  amount));   // $12,345.68
Console.WriteLine(string.Format("{0:C0}", amount));   // $12,346     (0 decimal places)

// D — decimal integer (integer types only)
Console.WriteLine(string.Format("{0:D}",  count));    // 42
Console.WriteLine(string.Format("{0:D6}", count));    // 000042      (zero-padded to 6 digits)

// F — fixed-point
Console.WriteLine(string.Format("{0:F}",  amount));   // 12345.68
Console.WriteLine(string.Format("{0:F4}", amount));   // 12345.6789  (4 decimal places)

// N — number with thousands separator
Console.WriteLine(string.Format("{0:N}",  amount));   // 12,345.68
Console.WriteLine(string.Format("{0:N0}", amount));   // 12,346      (no decimal places)

// P — percentage
Console.WriteLine(string.Format("{0:P}",  ratio));    // 18.75 %
Console.WriteLine(string.Format("{0:P1}", ratio));    // 18.8 %

// X — hexadecimal
Console.WriteLine(string.Format("{0:X}",  hex));      // FF
Console.WriteLine(string.Format("{0:X4}", hex));      // 00FF        (padded to 4 hex digits)

// E — scientific notation
Console.WriteLine(string.Format("{0:E}",  amount));   // 1.234568E+004
Console.WriteLine(string.Format("{0:E2}", amount));   // 1.23E+004

Alignment and Column Padding

A format item can include an alignment component: {index,width:format}. Positive width right-aligns; negative width left-aligns.

C# Example Code
// Right-align numbers in a column of width 10
Console.WriteLine(string.Format("{0,10}", "Amount"));
Console.WriteLine(string.Format("{0,10:C}", 9.99));
Console.WriteLine(string.Format("{0,10:C}", 1234.50));
Console.WriteLine(string.Format("{0,10:C}", 99999.00));

// Output:
//     Amount
//      $9.99
//  $1,234.50
// $99,999.00

// Left-align strings, right-align numbers — tabular report
var items = new[]
{
    ("Keyboard", 49.99m),
    ("Monitor",  299.00m),
    ("Mouse",    24.95m)
};

Console.WriteLine(string.Format("{0,-15} {1,10}", "Product", "Price"));
Console.WriteLine(new string('-', 26));
foreach (var (name, price) in items)
    Console.WriteLine(string.Format("{0,-15} {1,10:C}", name, price));

// Output:
// Product             Price
// --------------------------
// Keyboard           $49.99
// Monitor           $299.00
// Mouse             $24.95

Date and Time Formatting

C# Example Code
DateTime dt = new DateTime(2025, 6, 15, 14, 30, 0);

Console.WriteLine(string.Format("{0:d}",   dt)); // 6/15/2025           (short date)
Console.WriteLine(string.Format("{0:D}",   dt)); // Sunday, June 15, 2025
Console.WriteLine(string.Format("{0:t}",   dt)); // 2:30 PM             (short time)
Console.WriteLine(string.Format("{0:T}",   dt)); // 2:30:00 PM          (long time)
Console.WriteLine(string.Format("{0:f}",   dt)); // Sunday, June 15, 2025 2:30 PM
Console.WriteLine(string.Format("{0:g}",   dt)); // 6/15/2025 2:30 PM
Console.WriteLine(string.Format("{0:s}",   dt)); // 2025-06-15T14:30:00 (sortable ISO 8601)
Console.WriteLine(string.Format("{0:yyyy-MM-dd}", dt)); // 2025-06-15  (custom)

Custom Numeric Format Strings

Use #, 0, and other picture characters for fully custom layouts.

C# Example Code
double value = 1234567.89;

// # — digit placeholder (suppresses leading/trailing zeros)
Console.WriteLine(string.Format("{0:#,#}", value));        // 1,234,568
Console.WriteLine(string.Format("{0:#,#.##}", value));     // 1,234,567.89

// 0 — digit placeholder (forces zeros)
Console.WriteLine(string.Format("{0:000.000}", 7.5));      // 007.500

// Phone number pattern
long phone = 4155551234;
Console.WriteLine(string.Format("{0:(###) ###-####}", phone)); // (415) 555-1234

// Positive / negative / zero sections
Console.WriteLine(string.Format("{0:+#;-#;zero}", 42));    // +42
Console.WriteLine(string.Format("{0:+#;-#;zero}", -7));    // -7
Console.WriteLine(string.Format("{0:+#;-#;zero}", 0));     // zero

FAQ

When should I use string.Format instead of interpolation?

Use string.Format when the format template is stored externally or reused across many call sites. Use interpolation for straightforward inline message building.

Is string.Format still relevant in modern C#?

Yes, especially for localization, reusable templates, and scenarios where the format string is not hard-coded inline.

Culture-Aware Formatting

C# Example Code
using System.Globalization;

decimal price = 1234.56m;

var us = CultureInfo.GetCultureInfo("en-US");
var de = CultureInfo.GetCultureInfo("de-DE");
var jp = CultureInfo.GetCultureInfo("ja-JP");

Console.WriteLine(string.Format(us, "{0:C}", price)); // $1,234.56
Console.WriteLine(string.Format(de, "{0:C}", price)); // 1.234,56 €
Console.WriteLine(string.Format(jp, "{0:C}", price)); // ¥1,235

string.Format vs String Interpolation

Both produce the same output. Choose based on your scenario.

C# Example Code
string name  = "Alice";
decimal total = 249.99m;

// string.Format
string msg1 = string.Format("Hello, {0}! Your total is {1:C}.", name, total);

// String interpolation (C# 6+) — preferred for inline literals
string msg2 = $"Hello, {name}! Your total is {total:C}.";

// Both produce: "Hello, Alice! Your total is $249.99."
ScenarioPrefer
Inline, literal format stringString interpolation $"..."
Format string from a resource / configstring.Format
Localized UI messagesstring.Format with IFormatProvider
Logging frameworks (structured logging)Message templates ({PropertyName})
Building report columns with alignmentstring.Format with ,width

Take It Further

The C# Player's Guide book cover

The community's favorite C# guide — teaches every concept you just read about with clarity.

The C# Player's Guide — 5th Edition · RB Whitaker

Get it on Amazon →

As an Amazon Associate I earn from qualifying purchases.