Indexes and the [] operator
Every character in a string has a position called its index. Counting starts at zero, so the first character is at index 0, the second at index 1, and so on. To read the character at an index, put the index in square brackets after the string:
string message = "Hello world!";
char c = message[0];
Console.WriteLine(c); // H
c = message[1];
Console.WriteLine(c); // e
Console.WriteLine(message[6]); // w
The result is a char, C#'s type for a single character. Single characters are written in single quotes, like 'H', while strings use double quotes.
Spaces count too
Every character in the quotes is part of the string, spaces included. In "Hello world!" the space is at index 5, so w is at index 6. The characters at 4, 5 and 6 are o, a space and w.
A C# trap when joining chars
You might want to glue those three characters together with +. In C# that does not do what it does for strings:
string message = "Hello world!";
Console.WriteLine(message[4] + message[5] + message[6]);
262
Adding two char values adds their numeric codes (o is 111, space is 32, w is 119), so the result is the number 262. To join characters as text, start from a string, for example "" + message[4] + message[5] + message[6], or use interpolation, $"{message[4]}{message[5]}{message[6]}". Both print o w.
The last character
The last index is always one less than the length. The Length property gives the number of characters, so the last character is message[message.Length - 1]. For "Hello world!" that is index 11, the exclamation mark. Newer C# also accepts message[^1], where ^1 means "one from the end", and it gives the same character.
Reading every character
Once you know the length and the index rule, you can visit all the characters. A loop with an index from 0 up to Length - 1 reads each one in order. A later lesson covers loops. For now, remember that the first valid index is 0 and the last is Length - 1. An empty string "" has length 0, so it has no valid index at all.
Going out of range
An index must be between 0 and Length - 1. Anything else throws an IndexOutOfRangeException when the program runs, and the program stops with an error message. For a 12-character string, message[12] is already too far. Counting from 1 instead of 0 is the usual cause.
Strings are also immutable: you can read message[0], but you can't assign to it. A line like message[0] = 'J'; doesn't compile.
The exercise
The lesson gives you string fruit = "Avocado"; and asks for two prints:
- The first character. Index 0, so
Console.WriteLine(fruit[0]);printsA. - The last character. "Avocado" has seven characters (A, v, o, c, a, d, o), so the last index is 6.
Console.WriteLine(fruit[6]);printso. The expressionfruit[fruit.Length - 1]finds the same character without counting by hand.
string fruit = "Avocado";
Console.WriteLine(fruit[0]);
Console.WriteLine(fruit[6]);
The output is:
A
o
Console.WriteLine accepts a char and prints the character itself, so you don't need to convert it.
Why does the last index equal Length - 1? Because counting starts at 0, a string with seven characters uses the indexes 0 through 6. The count of characters and the index of the last one always differ by one. This off-by-one gap is behind many beginner bugs, so say it to yourself whenever you index a string.
Common mistakes
- Starting at 1.
fruit[1]is the second character,v, not the first. - Using
fruit[7]as the last. That is one past the end and throws an exception. The last index isLength - 1. - Using parentheses. Strings are indexed with square brackets.
fruit(0)would be read as a method call and fail to compile. - Adding chars with
+. It adds numbers, as shown above.
Key takeaways
- Indexes start at 0 and include spaces.
s[i]gives achar, and the valid range is 0 tos.Length - 1.- An out-of-range index throws
IndexOutOfRangeException. - Strings are read-only: you can read characters but not assign to them.