string.Format in C# — syntax, format specifiers, and examples

string.Format composes a string by replacing numbered placeholders ({0}, {1}, …) with supplied values. It has been superseded by string interpolation in most scenarios, but it remains the right choice when the format string is stored externally (config file, resource file, database) or when building reusable message templates.

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

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