Turning 42 into 00042 takes one call in C#: "42".PadLeft(5, '0') for a string, or 42.ToString("D5") for an int. Both give you a five-character result with zeros in front.
In this tutorial, I’ll show every way I use to add C# leading zeros: PadLeft, the D and 00000 formats, interpolation, negative numbers, values longer than the width, and trailing zeros. I ran each snippet on .NET 10 with dotnet run.
Add Leading Zeros to a String with PadLeft
The classic case is a ZIP code column that went through Excel. Excel treats 02108 as a number, so Boston’s ZIP comes back as 2108. Here’s how I fix the column after splitting each CSV row:
// ZIP codes from a CSV that went through Excel: the leading zero is gone
string[] rows = { "Boston,MA,2108", "Newark,NJ,7102", "Beverly Hills,CA,90210" };
foreach (string row in rows)
{
string[] cols = row.Split(',');
string zip = cols[2].PadLeft(5, '0');
Console.WriteLine($"{cols[0],-14} {cols[1]} {cols[2],5} -> {zip}");
}
Console.WriteLine("123456".PadLeft(5, '0'));
Console.WriteLine("42".PadLeft(5));
Output:
Boston MA 2108 -> 02108
Newark NJ 7102 -> 07102
Beverly Hills CA 90210 -> 90210
123456
42

PadLeft(5, '0') right-aligns the text and fills the left side with zeros until it’s five characters long. Boston’s 2108 becomes 02108, Newark’s 7102 becomes 07102, and 90210 is already five characters, so it’s unchanged.
The last two lines matter. A string longer than the width comes back as-is, never cut, and PadLeft(5) without a character pads with spaces.
Keep ZIP codes and account IDs as strings. They’re labels, not quantities, and storing them as int is how the zero gets lost. If you’re going the other way, see how to convert a string to int with leading zeros in C#.
Add Leading Zeros to an Integer with ToString(“D5”) and “00000”
When the value is already an int, skip the string step and format it directly. I use this for invoice numbers like INV-00042 and six-digit check numbers:
using System.Globalization;
CultureInfo.CurrentCulture = new CultureInfo("en-US");
int invoice = 42;
int check = 1047;
Console.WriteLine(invoice.ToString("D5"));
Console.WriteLine(invoice.ToString("00000"));
Console.WriteLine($"INV-{invoice:D5}");
Console.WriteLine($"INV-{invoice:00000}");
Console.WriteLine(string.Format("Check #{0:D6}", check));
Console.WriteLine($"Check #{check.ToString().PadLeft(6, '0')}");
double amount = 7.5;
Console.WriteLine(amount.ToString("00000.00"));
try { Console.WriteLine(amount.ToString("D5")); }
catch (FormatException) { Console.WriteLine("\"D5\" on a double throws FormatException"); }
Output:
00042
00042
INV-00042
INV-00042
Check #001047
Check #001047
00007.50
"D5" on a double throws FormatException

D5 means “decimal, at least five digits,” so 42 prints as 00042. The custom 00000 pattern gets the same result, since each 0 is a digit placeholder that’s filled with zero when empty.
These are the same format strings you’d pass to any ToString overload in C#, so they also work inside {invoice:D5}, {invoice:00000} and string.Format("{0:D6}", check).
Why Does “D” Throw a FormatException on a double?
The D specifier works on integral types only: byte, short, int, long and friends. Calling ToString("D5") on a double throws, as the last line shows.
For a double or decimal, use a custom pattern instead. "00000.00" turned 7.5 into 00007.50, padding both sides of the decimal point. The C# data types guide lists which types are integral.
How Do Leading Zeros Work with Negative Numbers?
This is where PadLeft and the number formats really split up. I ran a refund of -42 and a value that’s already wider than five digits through all three:
using System.Globalization;
CultureInfo.CurrentCulture = new CultureInfo("en-US");
int refund = -42;
int big = 123456;
Console.WriteLine(refund.ToString("D5"));
Console.WriteLine(refund.ToString("00000"));
Console.WriteLine(refund.ToString().PadLeft(5, '0'));
Console.WriteLine(big.ToString("D5"));
Console.WriteLine(big.ToString("00000"));
Console.WriteLine(big.ToString().PadLeft(5, '0'));
int width = 8;
Console.WriteLine(big.ToString($"D{width}"));
Console.WriteLine(big.ToString()[^5..]);
Output:
-00042
-00042
00-42
123456
123456
123456
00123456
23456

D5 and 00000 both print -00042: five digits, with the sign added in front. PadLeft(5, '0') sees the three characters -42 and produces 00-42, which is wrong.
So for numbers, always use a format string, not PadLeft on ToString().
What Happens When the Number Is Longer Than the Width?
None of the three methods truncate. 123456 stays 123456 with D5, 00000 and PadLeft, because the width is a minimum, not a maximum.
You can build the width at run time with $"D{width}". If you need an exact length, cut it yourself: [^5..] keeps the last five digits, 23456. For the front instead, see how to get the first N characters of a string in C#.
Add Trailing Zeros with PadRight, StringBuilder and “F3”
Trailing zeros mean two different things, depending on whether you have text or a number:
using System.Text;
using System.Globalization;
CultureInfo.CurrentCulture = new CultureInfo("en-US");
string account = "12345";
Console.WriteLine(account.PadRight(10, '0'));
var sb = new StringBuilder(account);
sb.Append('0', 3);
Console.WriteLine(sb.ToString());
decimal price = 12.5m;
Console.WriteLine(price.ToString("F3"));
Console.WriteLine(price.ToString("0.000"));
Console.WriteLine(string.Format("{0:0.00000}", price));
Console.WriteLine($"{price:0.00##}");
Output:
1234500000
12345000
12.500
12.500
12.50000
12.50

For a string, PadRight(10, '0') fills the right side, so 12345 becomes 1234500000. StringBuilder.Append('0', 3) adds an exact count of zeros instead of padding to a width. I compare when that’s worth it in string vs StringBuilder in C#.
For a number, don’t append characters. F3, 0.000 and {0:0.00000} set the decimal places, so 12.5 prints as 12.500. The 0.00## pattern keeps at least two decimals and up to four.
For rounding to cents, see how to show 2 decimal places in C#, and for grouping, how to format a number with commas in C#.
Which C# Leading Zeros Method Should You Use?
| You have | Use | Result |
|---|---|---|
| A string (ZIP code, ID) | s.PadLeft(5, '0') | 02108 |
| An int | n.ToString("D5") or $"{n:D5}" | 00042 |
| A negative int | D5 or 00000, never PadLeft | -00042 |
| A double or decimal | "00000.00" | 00007.50 |
| Trailing zeros on text | s.PadRight(10, '0') | 1234500000 |
| Decimal places | F3 or 0.000 | 12.500 |
The same idea works in other bases: X8 pads a hex string with leading zeros, and there’s a matching trick to convert an int to a binary string with leading zeros.
A few more string and number guides you might find handy:
- Check if a string is not null or empty in C#
- Convert a string to double in C#
- Convert null to int in C#
- Remove the last character from a string in C#
Frequently Asked Questions
How do I add leading zeros to a string in C#?
Call value.PadLeft(totalWidth, '0'). "2108".PadLeft(5, '0') returns “02108”. If the string is already longer than the width, PadLeft returns it unchanged. See String.PadLeft on Microsoft Learn.
How do I pad an int with leading zeros in C#?
Use number.ToString("D5"), the custom format "00000", or interpolation such as $"{number:D5}". All three turn 42 into 00042. Microsoft documents both approaches in How to pad a number with leading zeros.
Why does ToString(“D5”) fail on a double?
The D format specifier supports integral types only, so a double or decimal throws FormatException. Use a custom pattern like "00000.00" instead.
How do I keep the minus sign in front of the zeros?
Format the number with D5 or 00000; -42 prints as -00042. PadLeft on the string gives 00-42, because it treats the minus sign as a regular character.
Does PadLeft truncate a string that’s too long?
No. The width is a minimum. “123456”.PadLeft(5, ‘0’) returns “123456”. Use Substring if you need an exact length.
Should I store ZIP codes as int or string?
Store them as strings. A ZIP code is a label, and converting it to int drops the leading zero, as with Boston’s 02108.
Bijay Kumar is a renowned software engineer, accomplished author, and distinguished Microsoft Most Valuable Professional (MVP) specializing in SharePoint. With a rich professional background spanning over 15 years, Bijay has established himself as an authority in the field of information technology. He possesses unparalleled expertise in multiple programming languages and technologies such as ASP.NET, ASP.NET MVC, C#.NET, and SharePoint, which has enabled him to develop innovative and cutting-edge solutions for clients across the globe. Read more…