Dot Net Perls

IndexOf String Examples in C#

by Sam Allen - Updated June 13, 2009

Problem. You want to find the first occurrence of a letter in your string with IndexOf. Find letters in loops or simply the first or last occurrence. Solution. Look at ways to use IndexOf in loops. Here are some tips and samples.

1. Using IndexOf methods

There are 4 IndexOf methods here. The first two methods find the first indexes. They scan through the characters from the left to right. The second two find the last indexes, and they go from right to left.

Method: IndexOf
Use:    Finds first index of char.
        Returns -1 if not found.
        [MSDN source]

Method: IndexOfAny
Use:    Finds first index of any of the chars.
        Returns -1 if none are found.
        [MSDN source]

Method: LastIndexOf
Use:    Finds last index of char.
        [MSDN source]

Method: LastIndexOfAny
Use:    Finds last index of any in char group.
        [MSDN source]

2. Using IndexOf to test strings

Here we use IndexOf simply to see whether the input string contains a string. We want to see if the string in the example contains "Vader".

=== Example program that uses IndexOf ===

using System;

class Program
{
    static void Main()
    {
        // A.
        // The input string.
        const string s = "Darth Vader is really scary.";

        // B.
        // Test with IndexOf.
        if (s.IndexOf("Vader") != -1)
        {
            Console.Write("string contains 'Vader'");
        }
        Console.ReadLine();
    }
}

=== Output of the program ===

string contains 'Vader'

Description of the example. A. It has an input string. This string is what we want to test. B. It calls IndexOf. IndexOf returns the location of the string 'Vader'. It is not equal to -1, so the line is written to the Console.

3. Using IndexOf in loops

Here we see how you can use the method in loops. To do this, keep track of several values at once. You can loop through the instances of a char in a string. Here we loop over each 'a' in the string.

=== Example program that uses IndexOf in loop ===

using System;

class Program
{
    static void Main()
    {
        // A.
        // The input string.
        string s = "I have a cat";

        // B.
        // Loop through all instances of the letter a.
        int i = 0;
        while ((i = s.IndexOf('a', i)) != -1)
        {
            // C.
            // Print out the substring for demo.
            Console.WriteLine(s.Substring(i));

            // D.
            // Increment the index.
            i++;
        }
        Console.ReadLine();
    }
}

=== Output of the program ===

ave a cat
a cat
at

Description of IndexOf looping. A. It has an input string. This string is what we are testing with IndexOf. B. It uses a while loop. The while loop is the best way to do this. We test it for success each time. If the character isn't found, the loop will end.

Description of loop contents. C. It writes the result to the console. You don't need this part but it writes the Substring starting at i to the end of the string. D. The index is incremented. We must advance past the current character by adding one to the index. If you don't do this, you will get an infinite loop.

4. What does IndexOf return?

IndexOf will return -1 when it doesn't find anything, and the index if it does. This is a bit more a C-like behavior than .NET. The author has caused IndexOutOfRangeException by using the -1. This is different than the result from the Contains method. [See below for Contains method.]

5. Using IndexOf with Substring

You can use IndexOf with Substring. Here we get the first substring that begins with a certain pattern or character. The Substring method returns the rest of the string starting at your specified number. [C# Substring Samples - dotnetperls.com]

=== Example program that uses Substring ===

using System;

class Program
{
    static void Main()
    {
        // A.
        // Input.
        const string s = "I have a cat";

        // B.
        // Location of the letter c.
        int i = s.IndexOf('c');

        // C.
        // Remainder of string starting at 'c'.
        string d = s.Substring(i);
        Console.WriteLine(d);
        Console.ReadLine();
    }
}

=== Output of the program ===

cat

6. Using IndexOfAny on strings

Here we see how you can use the IndexOfAny method on strings in C#. You can use IndexOfAny on strings by providing a new char[] array. Use IndexOfAny when you need to test for multiple characters. Keep in mind that it is case-sensitive.

=== Example program uses IndexOfAny ===

using System;

class Program
{
    static void Main()
    {
        // A.
        // Input.
        const string s = "Darth is my enemy.";
        const string s2 = "Visual Basic is hard.";

        // B.
        // Find first location of 'e' or 'B'.
        int i1 = s.IndexOfAny(new char[] { 'e', 'B' });
        Console.WriteLine(s.Substring(i1));

        // C.
        // Find first location of 'e' or 'B'.
        int i2 = s2.IndexOfAny(new char[] { 'e', 'B' });
        Console.WriteLine(s2.Substring(i2));
        Console.ReadLine();
    }
}

=== Output of the program ===

enemy.
Basic is hard.

Description of IndexOfAny example. A. It uses an input. We scan through these two strings in the console program example. B. It finds first 's' or 'B'. The example here will find the 'e' in enemy, as no letter B is found.

Description of last two parts of example. C. It finds first 'B'. The 'B' in the parameters to IndexOfAny means it finds the word 'Basic' first. This example finds the first B instead of an e.

7. Benchmarking IndexOf

Here we test the IndexOf method against a single character iteration for loop. The author wanted to know if scanning through a string with a single char loop was faster than using IndexOf over each character. The results are noted after the example.

=== Char version ===

int c = 0;
for (int e = 0; e < s.Length; e++)
{
    if (s[e] == '.')
    {
        c++;
    }
}

=== IndexOf version ===

int c = 0;
int e = 0;
while ((e = s.IndexOf('.', e)) != -1)
{
    e++;
    c++;
}

=== Benchmark result ===

Char version:    1545 ms
IndexOf version: 2215 ms

Result of the benchmark. The author found that it is more efficient to scan each character individually than to use IndexOf. This may be because using IndexOf is more complex and therefore harder to optimize for the compiler.

8. What about LastIndexOf?

You can use LastIndexOf to search the source string just like IndexOf. LastIndexOf and LastIndexOfAny work the same way but in reverse. They still return -1 if the char cannot be found. These are used much less frequently.

9. Replacing your loop with IndexOf

Here we see how you can replace character iteration loops. Loops can be completely replaced with IndexOf in some situations. This can result in much clearer code. The following two pieces of code should perform about the same but the second is clearer for me.

=== For loop ===

int i = -1;
for (int y = 0; y < s.Length; y++)
{
    if (c == 'a')
    {
        i = y;
        break;
    }
}

=== Same loop with IndexOf ===

int i = s.IndexOf('a');

10. IndexOf with char vs. IndexOf with string

Here you want to know if there is a difference between calling IndexOf with a single character string parameter, and with a char parameter. If you call IndexOf with a string, globalization rules will be applied. Therefore, the string IndexOf will utilize more CPU cycles. However, even if you pass in StringComparison.Ordinal, it is slower.

=== IndexOf usage with string ===

int i = s.IndexOf("a");
// Finds first "a" string in s.

=== IndexOf usage with char ===

int i = s.IndexOf('a');
// Finds first 'a' char in s.

=== Benchmark result (ten million tests) ===

Char version:    1154 ms
IndexOf version: 172 ms

Interpretation of the results. What I found here is that calling IndexOf with a string is nearly 10x slower than calling it with a character. This is the case even with a single-character string.

11. Contains and IndexOf

Contains is a wrapper method that calls IndexOf with StringComparison.Ordinal. This means it has two major differences to remember. The first difference is that it returns true or false, not an integer. If its internal IndexOf returns -1, it returns false, otherwise it returns true. [C# Contains String Method - dotnetperls.com]

12. Summary

Here we saw several examples of using IndexOf. You will commonly use IndexOf to search for substrings in your strings; there is no method called Search, but the general idea is performed by IndexOf. These are powerful methods and are used in many programs with success.

Dot Net Perls
Strings | Environment.NewLine | Replace String Examples | Split String Examples | Substring Samples | Trim String Tips
C# | Dictionary StringComparer Tip | DateTime.TryParse Example | Reflection Field Example | Validate Characters in String
© 2009 Sam Allen. All rights reserved.