Search code examples
iphonexcodensstringnsrangeexception

NSRangeException even the range is correct in NSString Replace


I have written a code to replace delete the substring in NSString...my logic was to use 'rangeofString' to find the position of each substring characters and then using 'ReplaceOccurance' to replace the substring characters by space and later trimm the whitespace character. But am getting an error in replaceOccurance line as

*** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFString replaceOccurrencesOfString:withString:options:range:]: Range or index out of bounds'
*** First throw call stack:
(
    0   CoreFoundation                      0x00007fff85614b06 __exceptionPreprocess + 198
    1   libobjc.A.dylib                     0x00007fff83c4e3f0 objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff856148dc +[NSException raise:format:] + 204
    3   CoreFoundation                      0x00007fff85613520 -[__NSCFString replaceOccurrencesOfString:withString:options:range:] + 224
    4   Foundation                          0x00007fff8d433a12 -[NSString stringByReplacingOccurrencesOfString:withString:options:range:] + 170
    5   tester                              0x00000001000019a1 deleteWithSubstring + 865
    6   tester                              0x0000000100001d35 main + 133
    7   libdyld.dylib                       0x00007fff89e267e1 start + 0
    8   ???                                 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminate called throwing an exception....

Here is my code.

NSString* deleteWithSubstring(NSString *s1,NSString *sub)
{
    long int length=[sub length],range=0;
    NSRange r;
    for(int i=0;i<length;i++)
    {
        range=[s1 rangeOfString:[NSString stringWithFormat:@"%c",[sub characterAtIndex:i]]options:NSCaseInsensitiveSearch range:NSMakeRange(range,[s1 length]-1)].location;


        r=NSMakeRange(range,[s1 length]-1);
        NSLog(@"%ld %ld",r.location,r.length);
       if(range!=NSNotFound)
       {
           s1=[s1 stringByReplacingOccurrencesOfString:[NSString stringWithFormat:@"%c",[sub characterAtIndex:i]] withString:@" " options:NSCaseInsensitiveSearch range:r];
       }
    }
    s1=[s1 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
    return s1;
}

int main(int argc, const char * argv[])
{

    @autoreleasepool {


        NSString *str1,*str2;
        str1=@"Hdida";
        str2=@"fHsdai";

        NSLog(@"Loc B:%@ ",,deleteWithSubstring(str2,@"ha"));


    }
    return 0;
}

Actually i solved the problem with range..as rewriting the code i mistook the seocond argument is not the upperbound rather it is the length ..which should be as follows

   NSString* deleteWithSubstring(NSString *s1,NSString *sub)
    {
        long int length=[sub length],range=0,ndeleted=0;
        NSMutableString *s2=[[NSMutableString alloc]initWithString:s1];
        NSRange r;
        for(int i=0;i<length;i++)
        {
            range=[s1 rangeOfString:[NSString stringWithFormat:@"%c",[sub characterAtIndex:i]]options:NSCaseInsensitiveSearch range:NSMakeRange(range,[s1 length]-range)].location;


            r=NSMakeRange((range-ndeleted),1);
            NSLog(@"%ld %ld" ,r.location,r.length);
           if(range!=NSNotFound)
           {
               [s2 deleteCharactersInRange:r];
               ndeleted++;
           }
        }

        NSLog(@"%@",s2);
        return s2;
    }

Solution

  • Try the following code,

    NSString* deleteWithSubstring(NSMutableString *s1,NSString *sub)
    {
    
        NSRange r;
        for(int i = 0; i < [s1 length]; i++)
        {
            //findout the range with "sub" string
            r = [s1 rangeOfString:sub options:NSCaseInsensitiveSearch];
    
            if(r.location != NSNotFound)
            {
                //Delete the characters in that range
                [s1 deleteCharactersInRange:r];
            }
            else
            {
                //break the loop if sub string not found as there is no more recurrence.
                break;
            }
        }
        return s1;
    }
    
    int main(int argc, char *argv[])
    {
    
        @autoreleasepool {
            //initiating str1 here
            NSMutableString* str1 = [[NSMutableString alloc] init];
            [str1 appendString:@"fHsdaihati"];
    
            NSLog(@"Loc B:%@ ",deleteWithSubstring(str1,@"ha"));
        }
        return 0;
    }