Reza
Reza

Reputation: 211

Failed to use SUBSTRING in TryParse

I found an error in my code, where the subtring is not work, it says "startIndex cannot be larger than the length of string"

 static int MyIntegerParse(string possibleInt)
    {
        int i;
        return int.TryParse(possibleInt.Substring(2), out i) ? i : 0;        
    }

I used the procedure here:

var parsed = File.ReadLines(filename)
            .Select(line => line.Split(' ')     
                .Select(MyIntegerParse)
                .ToArray())
            .ToArray();

But I don't understand why it's error because I already used the substring before and it's work, can I ask for a help here? thnaks.

sample string:

10192 20351 30473 40499 50449 60234 
10192 20207 30206 40203 50205 60226 
10192 20252 30312 40376 50334 60252

Upvotes: 0

Views: 1039

Answers (5)

Fredrik Mörk
Fredrik Mörk

Reputation: 158359

Substring will fail when possibleInt contains fewer than two characters, so you should add that test to your code as well. I suspect that you Split call produces an empty string during some circumstances. This empty string is passed into your int-parser which then fails on the Substring call. So, you should probably do two things:

  • Get rid of empty strings in the splitting
  • Handle short or empty strings deliberately in your parsing code

Getting rid of empty strings is quite easy:

var parsed = File.ReadLines(filename)
            .Select(line => line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(MyIntegerParse)
                .ToArray())
            .ToArray();

Adding deliberate handling of empty strings can be done like so:

static int MyIntegerParse(string possibleInt)
{
    if (string.IsNullOrEmpty(possibleInt) || possibleInt.Length < 2)
    { 
        return 0;
    }

    int i;
    return int.TryParse(possibleInt.Substring(2), out i) ? i : 0;        
}

...or if you are a fan of compact and hard-to-read constructs:

static int MyIntegerParse(string possibleInt)
{
    int i;
    return (!string.IsNullOrEmpty(possibleInt) 
        && possibleInt.Length >= 2
        && int.TryParse(possibleInt.Substring(2), out i)) ? i : 0;        
}

No, I have chosen to return 0 when I get strings that are too short. In your case it might make more sense to return some other value, throw an exception or use a Debug.Assert statement.

Upvotes: 1

Tejs
Tejs

Reputation: 41256

The line you are attempting to parse is not that long. From the C# Specification on Substring:

The zero-based starting character position of a substring in this instance. 

The string you are passing in either has 0 or 1 characters in it. You need to modify your code to handle such a situation.

EDIT: Additionally, you should be removing empty elements from your file using an overload of split:

.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntires)

Upvotes: 0

jmccarthy
jmccarthy

Reputation: 480

You are getting this exception because you are trying to get the substring of a string starting at an index that is greater than the length of the string.

someString.Substring(x) will give you the substring of someString starting at position x in the string, and it is zero based. You are getting this exception because in this case 2 is outside the range of the particular strings length.

Stick a try catch around it, or a breakpoint and you will see the string that is causing this exception has a length less than 3.

Upvotes: 0

BrandonZeider
BrandonZeider

Reputation: 8152

Add this before your return statement and see if that helps you figure out what's going on:

Debug.Assert(!string.IsNullOrEmpty(possibleInt) && possibleInt.Length > 2);

When running in Debug mode this will throw an exception if the two cases above are not met.

You could also use a Code Contract like this:

Contract.Assert(!string.IsNullOrEmpty(possibleInt) && possibleInt.Length > 2);

Upvotes: 0

LukeH
LukeH

Reputation: 269528

The possibleInt string needs to be at least two characters long. When it isn't then you'll see the error that you've described.

Upvotes: 0

Related Questions