Home
C#
String IndexOf Examples
This page was last reviewed on Nov 15, 2023.
Dot Net Perls
IndexOf. From the start to the end, the IndexOf method in C# searches one string for another. It returns the index of the string part, if one is found.
Shows a loop
Return value. If the substring or char is not found, IndexOf returns -1. If we test for positive values, we can tell if the value was present.
An example. We use IndexOf to see if a string contains a word. Usually we want to know the exact result of IndexOf. We can store its result in an int local.
Part 1 IndexOf returns the location of the string "dog." It is located at index 4.
Part 2 We test the result of IndexOf against the special constant -1. The string "turnip" is not found, so we get -1.
using System; string value = "cat,dog"; // Part 1: find index of dog. Console.WriteLine(value.IndexOf("dog")); // Part 2: test not found value. if (value.IndexOf("turnip") == -1) { Console.WriteLine("?"); }
4 ?
While loop. We often use IndexOf in loops. We have to keep track of several values at once. This prevents us from searching the same parts over and over again.
while
Argument 1 The first argument to IndexOf here is the character we are searching for—in this case the lowercase letter "a."
Argument 2 This is the start index we want to search from in the source string. With the initial value 0, we begin at the first char.
Warning We must advance past the current character by adding 1 to the index. If we do not do this, we will get an infinite loop.
Shows a loop
using System; // The input string. string s = "I have a cat"; // Loop through all instances of the letter a. int i = 0; while ((i = s.IndexOf('a', i)) != -1) { // Print out the substring. Console.WriteLine(s.Substring(i)); // Increment the index. i++; }
ave a cat a cat at
Return value. This is -1 when IndexOf does not find anything, and the index if it does. Often an IndexOutOfRangeException can provoked by using the -1 in other code (like an array access).
So Please be careful when using IndexOf. It is probably better to check for negative one at least once in most places.
using System; string source = "big dog"; // See result of IndexOf method. Console.WriteLine("NOT FOUND: {0}", source.IndexOf("cat")); Console.WriteLine("FOUND: {0}", source.IndexOf("dog"));
NOT FOUND: -1 FOUND: 4
Substring. We can use IndexOf with the Substring method. Here we get the first substring that begins with a certain pattern or character.
Info The Substring method returns the rest of the string starting at a specified number.
String Substring
using System; // Input. const string s = "I have a cat"; // Location of the letter c. int i = s.IndexOf('c'); // Remainder of string starting at c. string d = s.Substring(i); Console.WriteLine(d);
cat
Skip start. Often strings have leading characters that we know cannot contain the searched-for value. We can skip these chars. This will give a performance boost—less searching is needed.
using System; string value = ":100,200"; // Skip the first character with a startIndex of 1. int comma = value.IndexOf(',', 1); Console.WriteLine(comma);
4
IndexOfAny. This method receives a char array argument. It searches for the first index of any of the characters provided in that array.
String IndexOfAny
Note This method is similar to calling IndexOf several times with the logical "or" operator.
However IndexOfAny has different performance characteristics. It may result in clearer code.
using System; var code = "xyz"; // Use IndexOfAny to find an "a" or "z". int result = code.IndexOfAny(new char[] { 'a', 'z' }); if (result != -1) { Console.WriteLine("a or z found at {0}", result); }
a or z found at 2
LastIndexOf. This works like IndexOf, but searches in reverse, from the right to the left part of the string. It starts with the last char.
String LastIndexOf
Here We try to find the last underscore char in the string. We find one at index 7, even though an earlier one occurs in the source string.
Also LastIndexOfAny searches in reverse, and tests the character array for any match.
using System; var code = "cat_dog_?"; // Find last underscore. int result = code.LastIndexOf('_'); if (result != -1) { Console.WriteLine("_ found at {0}", result); }
_ found at 7
Contains. This is a wrapper method. It calls IndexOf with StringComparison.Ordinal. It returns true or false, not an integer—so it is a bit simpler to use.
String Contains
Detail If Contains internal IndexOf returns -1 contains returns false. Otherwise it returns true.
using System; var name = "red paint"; // Use Contains to see if a string is found in a source string. if (name.Contains("paint")) { Console.WriteLine("paint found!"); }
paint found!
Benchmark, for-loop. Should we prefer IndexOf over for-loops when-possible? Scanning a string is a common operation. Choosing the fastest code here could help many programs.
Version 1 Here we use a single-character iteration for-loop. We see the "for" and "if" keywords in the code.
Version 2 This version of the code uses the IndexOf() method with a single char argument to search a string.
Result It is more efficient to scan each character individually than to use IndexOf.
Note The internal code for IndexOf is more complex—it is harder to optimize for the compiler.
using System; using System.Diagnostics; const int _max = 1000000; string s = "abc.123.456.xyz"; // Version 1: use for-loop to count chars. var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { int c = 0; for (int e = 0; e < s.Length; e++) { if (s[e] == '.') { c++; } } } s1.Stop(); // Version 2: use IndexOf to count chars. var s2 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { int c = 0; int e = 0; while ((e = s.IndexOf('.', e)) != -1) { e++; c++; } } s2.Stop(); // Result times. Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns"));
18.21 ns: For-loop 26.78 ns: IndexOf, while-loop
Benchmark, char argument. Sometimes we are searching for a single character. We can specify this single character as a 1-char string, or a char.
Version 1 Here we invoke IndexOf with a char argument. We use a char instead of a string, but the output is the same.
Version 2 This version of the code calls IndexOf with a single-character string argument.
Result The string IndexOf will require more CPU cycles. And even if we pass in StringComparison.Ordinal, it is slower.
So A char argument is more efficient. Using a string is many times slower than using a char value.
using System; using System.Diagnostics; const int _max = 1000000; string value = "The puppy is adorable."; // Version 1: use char argument. var s1 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { int result = value.IndexOf('a'); } s1.Stop(); // Version 2: use string argument. var s2 = Stopwatch.StartNew(); for (int i = 0; i < _max; i++) { int result = value.IndexOf("a"); } s2.Stop(); // Result times. Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns")); Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) / _max).ToString("0.00 ns"));
13.07 ns: IndexOf char argument 226.86 ns: IndexOf string argument
Array.IndexOf. We call IndexOf on strings, but we can also use (different) IndexOf methods on arrays and Lists. These also return -1 if nothing is found.
Array.IndexOf
We commonly use IndexOf to search for chars (or substrings) in strings. For complex problems, a for-loop may be easier to write and faster to execute.
Dot Net Perls is a collection of tested code examples. Pages are continually updated to stay current, with code correctness a top priority.
Sam Allen is passionate about computer languages. In the past, his work has been recommended by Apple and Microsoft and he has studied computers at a selective university in the United States.
This page was last updated on Nov 15, 2023 (simplify).
Home
Changes
© 2007-2024 Sam Allen.