Extracting a string with substringWithRange: gives "index out of bounds"

Ray Y picture Ray Y · May 19, 2011 · Viewed 55k times · Source

When I try to extract a string from a larger string it gives me a range or index out of bounds error. I might be overlooking something really obvious here. Thanks.

NSString *title = [TBXML textForElement:title1];
TBXMLElement * description1 = [TBXML childElementNamed:@"description" parentElement:item1];
NSString *description = [TBXML textForElement:description1];
NSMutableString *des1 = [NSMutableString stringWithString:description];

//search for <pre> tag for its location in the string
NSRange match;
NSRange match1;
match = [des1 rangeOfString: @"<pre>"];
match1 = [des1 rangeOfString: @"</pre>"];
NSLog(@"%i,%i",match.location,match1.location);
NSString *newDes = [des1 substringWithRange: NSMakeRange (match.location+5, match1.location-1)]; //<---This is the line causing the error

NSLog(@"title=%@",title);
NSLog(@"description=%@",newDes);

UPDATE: The 2nd part of the range is a length, not the endpoint. D'oh!

Answer

executor21 picture executor21 · May 19, 2011

The second parameter passed to NSMakeRange isn't the end location, it's the length of the range.

So the code above tries to find a substring that begins at the first character following <pre> and ends N characters after that, where N is the index of the last character before within the whole string.

Example: in the string "wholeString<pre>test</pre>noMore" ", the first 't' of 'test' has index 16 (first character has index 0), and the final 't' of 'test' has, therefore, index 19. The code above would call NSMakeRange(16, 19), which would include 19 characters, starting with the first 't' of 'test'. But there are only 15 characters, inclusive, from the first 't' of 'test' till the end of the string. Therefore, you get the out of bounds exception.

What you need is to call NSRange with the appropriate length. For the above purpose, it'd be NSMakeRange(match.location+5, match1.location - (match.location+5))