Text is everywhere in software: names, messages, email addresses, file paths, search queries, JSON. In C#, text is stored in a string, a sequence of characters written in double quotes.
C# gives strings a rich set of built-in methods. You can change their case, search inside them, cut out parts, replace words, split a line of comma-separated values into pieces and join them back together. String interpolation, written with a $ before the opening quote, lets you drop variables and even calculations straight into text, with formatting for prices and dates.
One important detail: C# strings are immutable. Methods like ToUpper never change the original string; they return a new one. In this lesson you'll learn the most useful string methods, format numbers neatly, handle special characters, and use StringBuilder when you need to build a long piece of text step by step.
Creating and combining strings
string first = "Ada";
string last = "Lovelace";
string full = first + " " + last; // concatenation
string greeting = $"Hello, {first}!"; // interpolation
string sum = $"2 + 3 = {2 + 3}"; // expressions work toofull.Lengthgives the number of characters.full[0]gives the first character, achar. Indexes start at 0, andfull[^1]gives the last character.- Interpolation is easier to read than
+when there are several values.
Common string methods
| Method | Example | Result |
|---|---|---|
ToUpper() / ToLower() | "Hi".ToUpper() | "HI" |
Trim() | " hi ".Trim() | "hi" |
Contains(x) | "hello".Contains("ell") | true |
StartsWith(x) / EndsWith(x) | "file.txt".EndsWith(".txt") | true |
IndexOf(x) | "banana".IndexOf("n") | 2 (or -1 if not found) |
Substring(start, length) | "Codevra".Substring(0, 4) | "Code" |
Replace(a, b) | "a-b-c".Replace("-", "+") | "a+b+c" |
Split(',') | "a,b,c".Split(',') | ["a", "b", "c"] |
string.Join(", ", items) | string.Join("-", parts) | "a-b-c" |
string.IsNullOrWhiteSpace(s) | string.IsNullOrWhiteSpace(" ") | true |
Formatting, escapes and raw strings
Add a format specifier after a colon inside interpolation braces:
{price:F2}gives two decimal places:19.50.{count:N0}adds thousands separators:1,234,567.{ratio:P0}shows a percentage:75%.{name,-10}pads to 10 characters, which lines up columns.
Escape sequences start with a backslash: \n new line, \t tab, \" a quote, \\ a backslash. A verbatim string, @"C:\files\data.txt", treats backslashes literally. Raw string literals, wrapped in three quotes """, can span lines and contain quotes without escaping, which is perfect for JSON samples.
Slicing with ranges and indexes
Besides Substring, modern C# lets you cut out part of a string with a range, written start..end. The start is included and the end is excluded, and ^ counts from the end:
string word = "Codevra";
Console.WriteLine(word[..4]); // Code (first four characters)
Console.WriteLine(word[1..4]); // ode (indexes 1, 2 and 3)
Console.WriteLine(word[^3..]); // vra (last three characters)
Console.WriteLine(word[^1]); // a (last character, a char)Ranges are often easier to read than Substring(start, length), because you write where to stop rather than how many characters to take. Both throw an ArgumentOutOfRangeException if you go past the end, so check Length first when the text comes from a user. The result of a range on a string is always a new string, because the original can never change, and the same syntax works on arrays.
Working with individual characters
A string is a sequence of char values, so you can loop over it with foreach and test each character with the static methods on char:
int digits = 0;
foreach (char c in "Room 101")
{
if (char.IsDigit(c)) digits++;
}
Console.WriteLine(digits); // 3Useful checks include char.IsLetter, char.IsDigit, char.IsWhiteSpace and char.IsUpper, and char.ToUpper('q') gives 'Q'. Each char is also a number underneath: (int)'A' is 65 and (char)66 is 'B'.
Because strings are immutable, you can't write word[0] = 'J'. When you need to change individual characters, copy them into an array, edit it and build a new string:
char[] letters = "hello".ToCharArray();
letters[0] = 'j';
string changed = new string(letters); // "jello"new string('-', 10) is a related shortcut that repeats one character, which is handy for underlining headings in console output.
C# Strings Syntax
String operations
string s = " Hello World ";
s.Trim().ToLower() // "hello world"
s.Contains("World") // true
s.Trim().Split(' ') // ["Hello", "World"]
string.Join(", ", new[] { "a", "b" }) // "a, b"
$"{price:F2}" $"{big:N0}" $"{share:P1}"
"line1\nline2" @"C:\temp" """He said "hi" """
var sb = new System.Text.StringBuilder();
sb.Append("a").AppendLine("b");
string result = sb.ToString();C# Strings Summary
- Strings are text in double quotes; $"...{x}..." interpolates values and expressions.
- Length, indexing from 0 and ^1 for the last character.
- ToUpper, Trim, Contains, IndexOf, Substring, Replace, Split and Join cover most tasks.
- Format specifiers such as :F2 and :N0 control how numbers appear.
- Strings are immutable; use StringBuilder to build long text in steps.
C# Strings Examples
Each example shows the code, the output it produces and what each part does.
Cleaning up a name
string input = " ada LOVELACE ";
string trimmed = input.Trim();
string[] parts = trimmed.Split(' ');
string first = parts[0][0].ToString().ToUpper() + parts[0].Substring(1).ToLower();
string last = parts[1][0].ToString().ToUpper() + parts[1].Substring(1).ToLower();
Console.WriteLine($"[{trimmed}]");
Console.WriteLine($"{first} {last}");
Console.WriteLine($"Initials: {first[0]}{last[0]}");
Console.WriteLine($"Length: {first.Length + last.Length}");[ada LOVELACE]
Ada Lovelace
Initials: AL
Length: 11Line-by-line explanation
- Line 2Trim removes spaces from both ends.
- Line 3Split breaks the text at each space into an array.
- Line 5The first letter is uppercased and the rest of the word lowercased.
- Line 10Indexing a string gives a char.
- Line 11Ada has 3 letters and Lovelace has 8.
Formatting a receipt
string[] items = { "Coffee", "Croissant", "Orange juice" };
decimal[] prices = { 2.8m, 2.25m, 3.5m };
decimal total = 0;
for (int i = 0; i < items.Length; i++)
{
Console.WriteLine($"{items[i],-14}{prices[i],6:F2}");
total += prices[i];
}
Console.WriteLine(new string('-', 20));
Console.WriteLine($"{"Total",-14}{total,6:F2}");
Console.WriteLine($"Visitors: {1234567:N0}");Coffee 2.80
Croissant 2.25
Orange juice 3.50
--------------------
Total 8.55
Visitors: 1,234,567Line-by-line explanation
- Line 7,-14 pads the name to 14 characters on the left; ,6:F2 right-aligns the price in 6 characters with two decimals.
- Line 10new string('-', 20) repeats a character 20 times.
- Line 12N0 adds thousands separators (shown here with English formatting).
Searching, replacing and StringBuilder
using System.Text;
string email = "Ada.Lovelace@Example.com";
int at = email.IndexOf('@');
string user = email.Substring(0, at);
string domain = email[(at + 1)..].ToLower();
Console.WriteLine(user);
Console.WriteLine(domain);
Console.WriteLine(email.EndsWith(".com"));
Console.WriteLine(string.Equals(email, "ada.lovelace@example.com", StringComparison.OrdinalIgnoreCase));
Console.WriteLine("2026-03-01".Replace("-", "/"));
var sb = new StringBuilder();
for (int i = 1; i <= 3; i++)
{
sb.Append($"Row {i}; ");
}
Console.WriteLine(sb.ToString().TrimEnd());Ada.Lovelace
example.com
True
True
2026/03/01
Row 1; Row 2; Row 3;Line-by-line explanation
- Line 4IndexOf finds the position of the @ sign.
- Line 5Substring(0, at) takes everything before it.
- Line 6[(at + 1)..] is a range: everything after the @.
- Line 11OrdinalIgnoreCase compares without caring about capital letters.
- Lines 14 to 18StringBuilder adds pieces to one buffer instead of creating a new string each time.
- Line 19TrimEnd removes the trailing space.
Common C# Strings Mistakes
Expecting a method to change the string
string name = "ada";
name.ToUpper();
Console.WriteLine(name); // still "ada"string name = "ada";
name = name.ToUpper();Building a big string with += in a loop
string report = "";
foreach (var line in lines) report += line + "\n"; // slow for thousands of linesvar sb = new StringBuilder();
foreach (var line in lines) sb.AppendLine(line);
string report = sb.ToString();Backslashes in a normal string
string path = "C:\new\test.txt"; // \n and \t become a new line and a tabstring path = @"C:\new\test.txt";C# Strings in Real Projects
Strings in applications
Web APIs trim and validate form fields, compare emails ignoring case, and build messages with interpolation. Import tools split CSV lines with Split(','). Logging libraries use interpolation-style templates, and report generators use StringBuilder to assemble large documents. Raw string literals keep JSON and SQL samples readable in tests.
C# Strings FAQ
How do I check if a string is empty or null in C#?
Use string.IsNullOrEmpty(s) to catch both null and "", or string.IsNullOrWhiteSpace(s) to also treat strings made only of spaces as empty. The second is usually the better choice for user input. Checking s.Length == 0 on its own throws a NullReferenceException when s is null.
What is the difference between string interpolation and string.Format?
Both produce the same text. Interpolation, $"Total: {total:F2}", puts the values directly inside the braces, while string.Format("Total: {0:F2}", total) uses numbered placeholders and a separate argument list. Interpolation is easier to read and is the usual choice in modern C#.
How do I split a string and ignore empty entries?
Pass StringSplitOptions.RemoveEmptyEntries: "a,b,,c".Split(',', StringSplitOptions.RemoveEmptyEntries) gives three items instead of four. Add StringSplitOptions.TrimEntries as well, combined with |, to remove spaces around each piece.
Why can't I change a character in a C# string?
Strings are immutable, so the indexer s[0] is read-only and s[0] = 'X' doesn't compile. Build a new string instead, for example with Replace, with ranges and concatenation, or by editing a char[] from ToCharArray() and passing it to new string(...). For lots of changes, use StringBuilder.
When should I use StringBuilder instead of +?
Use StringBuilder when you build a string in a loop or from many pieces, because each + creates a brand-new string and copies everything so far. For joining a few values on one line, + or interpolation is perfectly fine and easier to read.
C# Strings Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Complete the code so the message includes the name.
string name = "Sam";
Console.WriteLine("Hi {name}");
What does this print?
Console.WriteLine("banana".IndexOf("n"));
What does this print?
string s = "a,b,,c";
Console.WriteLine(s.Split(',').Length);
What does $"{9.5:F2}" produce?
Why is StringBuilder faster than += when building a long string in a loop?
C# Strings Quiz
5 questions to check what you learned.
What does
"Hello".Lengthreturn?- 4
- 5
- 6
- "Hello"
How do you compare two strings ignoring case?
- a == b
- string.Equals(a, b, StringComparison.OrdinalIgnoreCase)
- a.Compare(b)
- a.ToUpper() = b
What does @ before a string literal do?
- Interpolates values
- Makes it a char
- Makes it constant
- Makes a verbatim string where backslashes are literal
What does
"Codevra".Substring(4)return?- "Code"
- "evra"
- "vra"
- "v"
What does
"abc"[^1]give?- 'c'
- 'a'
- 'b'
- An error