web-dev-qa-db-ja.com

substringWithRangeで文字列を抽出すると、「範囲外のインデックス」が得られます

大きな文字列から文字列を抽出しようとすると、範囲外または範囲外のインデックスエラーが発生します。ここで本当に明らかなことを見落としているかもしれません。ありがとう。

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);

更新:範囲の2番目の部分は、エンドポイントではなく長さです。D'oh!

29
Ray Y

NSMakeRangeに渡される2番目のパラメーターは終了位置ではなく、範囲の長さです。

そのため、上記のコードは、_<pre>_に続く最初の文字でbeginsおよびN文字の後のendsである部分文字列を見つけようとしますここで、Nは文字列全体の前の最後の文字のインデックスです。

例:文字列_"wholeString<pre>test</pre>noMore"_で、「test」の最初の「t」のインデックスは16(最初の文字のインデックスは0)であり、「test」の最後の「t」のインデックスは19です。上記のコードはNSMakeRange(16, 19)を呼び出しますが、これには 'test'の最初の 't'から始まる19文字が含まれますが、 'test'の最初の 't'から15文字しか含まれていません。文字列の終わり。したがって、境界外の例外が発生します。

必要なのは、適切な長さでNSRangeを呼び出すことです。上記の目的では、NSMakeRange(match.location+5, match1.location - (match.location+5))になります

39
executor21

これを試して

NSString *string = @"www.google.com/api/123456?google/Apple/document1234/";
//divide the above string into two parts. 1st string contain 32 characters and remaining in 2nd string
NSString *string1 = [string substringWithRange:NSMakeRange(0, 32)];
NSString *string2 = [string substringWithRange:NSMakeRange(32, [string length]-[string1 length])];
NSLog(@"string 1 = %@", string1);
NSLog(@"string 2 = %@", string2);

String2では、最後の文字のインデックスを計算しています

出力:

string 1 = www.google.com/api/123456?google
string 2 = /Apple/document1234/
6
vishnu