17

I am currently developing an application in C# where I need to get the substring after a certain character within the string.

else if (txtPriceLimit.Text.Contains('.') && char.IsNumber(e.KeyChar))
{
    int index = txtPriceLimit.Text.IndexOf('.');
    string pennies = txtPriceLimit.Text.Substring(index, txtPriceLimit.Text.Length);
    Console.WriteLine("Pennies: " + pennies);
}

For some reason it keeps on coming up with an IndexOutOfRangeException. How can I get the contents of the string from the index to the end?

Thanks for any help you can provide.

EDIT: Just found that the various things I have tried that have been suggested do seem to work except its not getting the value from the last button pressed into the text field. I am using the KeyPress Event in order to do this.

For example if I enter .123 it will only print 12. Then if I add 4 on the end it will print 123

1
  • To add to Donut's answer. The reason your Substring() call is failing is because you're asking for txtPriceLimit.Text.Length characters starting from index. Meaning the entire length of your string would have to be index + txtPriceLimit.Text.Length. Commented Feb 24, 2011 at 17:48

6 Answers 6

33

The overload of String.Substring that you're using takes a start index and a specified length. As the start index, you're using the location of ".", but as the length, you're using the length of the entire string. If index is greater than 0, this will cause an exception (as you've seen).

Instead, just use this:

string pennies = txtPriceLimit.Text.Substring(index + 1);

This will get all of the characters within txtPriceLimit.Text after the location of ".". Note that we need to add 1 to the index; otherwise "." will be included in the resulting substring.

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks, I did try this but it is only getting the values before the indexof
@Boardy Not quite sure what you mean here, could you please clarify? Does txtPriceLimit.Text contain more than one period?
@Donut No only contains 1 one period. Sorry I misread the output it is getting the numbers after the point except for the last character. For example if I type 100.501 instead of it printing 501 it will print 50
@Boardy: It looks like you're doing this in a keydown handler or some such. Have you checked to see that txtPriceLimit.Text has been updated to include the number that the user just entered?
@Donut I'm using a KeyPress. Surely calling txtPriceLimit.Text should get the last entered character when the method was called but it doesn't seem to be doing it
|
4

Just try doing this instead

string pennies = txtPriceLimit.Text.Split('.')(1);

This assumes that there is only 1 . in the string, and that there will be 1 in the string.

2 Comments

Assumes there's only two string parts.
string pennies = txtPriceLimit.Text.Split('.').LastOrDefault()
3

It looks like a lot of people are finding this useful, so I wanted to contribute some code I created to the community.

This is an extension method I wrote that will return the text in this string txt following the parameter string value:

Listing 1:

public static string TextFollowing(this string txt, string value) {
  if (!String.IsNullOrEmpty(txt) && !String.IsNullOrEmpty(value)) {
    int index = txt.IndexOf(value);
    if (-1 < index) {
      int start = index + value.Length;
      if (start <= txt.Length) {
        return txt.Substring(start);
      }
    }
  }
  return null;
}

Example 1:

string exampleText = "My cat is bad.";
string afterCat = exampleText.TextFollowing("cat");
// afterCat = " is bad.";

For people who have not come over to Extension Methods, you can get the same results out of a tool similarly defined like this:

Listing 2:

public static string TextFollowing(string searchTxt, string value) {
  if (!String.IsNullOrEmpty(searchTxt) && !String.IsNullOrEmpty(value)) {
    int index = searchTxt.IndexOf(value);
    if (-1 < index) {
      int start = index + value.Length;
      if (start <= searchTxt.Length) {
        return searchTxt.Substring(start);
      }
    }
  }
  return null;
}

Example 2:

string exampleText = "My cat is bad.";
string afterCat = TextFollowing(exampleText, "cat");
// afterCat = " is bad.";

In each of the examples above, if exampleText had been an Empty String, the search value had been null or Empty String, or if the search value is not found, the resulting string would be null.

I have this code in my list of tools where it is used in countless places in numerous projects, and it always works great.

Comments

2

Use this , this will definitely work :-

else if (txtPriceLimit.Text.Contains('.') && char.IsNumber(e.KeyChar))
{
    int index = txtPriceLimit.Text.IndexOf('.');
    string pennies = txtPriceLimit.Text.Substring(index+1, txtPriceLimit.Text.Length-(index+1));
    pennies=pennies+e.KeyChar.ToString();
    Console.WriteLine("Pennies: " + pennies);
}

Comments

1

Donut's answer is the right one.

Because the second parameter of Substring is length not 'end index', his answer is the much cleaner equivalent of:

string pennies = txtPriceLimit.Text.Substring(index, index-txtPriceLimit.Text.Length);

2 Comments

Thanks I tried this but it is still coming up with an indexoutofrange exception
KeyPress event is to let you accept or deny - the text has NOT been updated yet - and the pending character is in e.KeyChar. If you are not rejecting input - change to using txtPriceLimit.TextChanged event (msdn.microsoft.com/en-us/library/…)
0

VisualBasic version

Code to find sub-string, if found, return the trailing part - the remainder of the string immediately behind (trailing the end) of the found sub-string.

jp2code's answer fitted my purpose in an elegant fashion. In addition to examples, the author also indicated the code has been well tried and tested over time. VisualBasic equivalent of his/her code:

Imports System.Runtime.CompilerServices

Module StringExtensions
    <Extension()>
    Public Function TextFollowing(txt As String, value As String) As String
        If Not String.IsNullOrEmpty(txt) AndAlso Not String.IsNullOrEmpty(value) Then
            Dim index As Integer = txt.IndexOf(value)
            If -1 < index Then
                Dim start As Integer = index + value.Length
                If start <= txt.Length Then
                    Return txt.Substring(start)
                End If
            End If
        End If
        Return Nothing
    End Function
End Module

The code has been tested using VS Community 2017.

Usage example

Dim exampleText As String = "C-sharp to VisualBasic"
Dim afterCSharp = exampleText.TextFollowing("to")
'afterCSharp = " VisualBasic"

The extension method TextFollowing() is now avaliable to String objects.

  1. Line 1: exampleText is String and therefore our extension method is available
  2. Line 2: exampleText.TextFollowing() uses the extension method

Complementary method

It may be useful to have the complementary method - obtain the preceding portion of the string. The complementary extension methods are written and placed together in one combined code module:

Imports System.Runtime.CompilerServices

Module StringExtensions
    <Extension()>
    Public Function TextFollowing(txt As String, value As String) As String
        If Not String.IsNullOrEmpty(txt) AndAlso Not String.IsNullOrEmpty(value) Then
            Dim index As Integer = txt.IndexOf(value)
            If -1 < index Then
                Dim start As Integer = index + value.Length
                If start <= txt.Length Then
                    Return txt.Substring(start)
                End If
            End If
        End If
        Return Nothing
    End Function
    <Extension()>
    Public Function TextPreceding(txt As String, value As String) As String
        If Not String.IsNullOrEmpty(txt) AndAlso Not String.IsNullOrEmpty(value) Then
            Dim index As Integer = txt.IndexOf(value)
            If -1 < index Then
                Return txt.Substring(0, index)
            End If
        End If
        Return Nothing
    End Function
End Module

Usage example

Dim exampleText As String = "C-sharp to VisualBasic"
Dim beforeVisualBasic = exampleText.TextPreceding("to")
'beforeVisualBasic = "C-sharp "

In my use case, it is necessary to check if LargeString.Contains(SmallString) prior to using these extension methods. For faster code execution this could have been combined with the extension methods presented above which I did not. This is because no slow-ness is experienced therefore the preference is on code reusability.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.