Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Substring with range out of bounds?

Okay, so this is a bit confusing (well to me). I have a string that has a single number I want out of it. I have surrounded this number with '/' so that I will be able to get that number out of it later.

Here is how I am getting the number out of it:

if ([MYSTRING hasSuffix:@"mp"]) {
        int start = 0;
        int end = 0;
        char looking = '/';
        for(int i=0; i < MYSTRING.length; i++){
            if (looking == [MYSTRING characterAtIndex:i]) {
                if (start == 0) {
                    start = i;
                }
                else{
                    end = i + 1;
                }
            }
        }
        NSLog(@"%@", MYSTRING); //When i NSLOG here i get '2012-06-21 03:58:00 +0000/1/mp', 1 is the number i want out of the string, but this number could also change to 55 or whatever the user has
        NSLog(@"start: %i, end: %i", start, end); //When i NSLOG here i get 'start: 25, end: 28'
        NSString *number = [MYSTRING substringWithRange:NSMakeRange(start, end)];
        number = [number stringByReplacingOccurrencesOfString:@"/" withString:@""];
        if ([number intValue] > numberInt) {
            numberInt = [number intValue];
        }

It keeps crashing and the console says:

* Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFString substringWithRange:]: Range or index out of bounds' * First throw call stack: (0x1875d72 0x106ce51 0x1875b4b 0x184ea64 0x3a6c 0x1080713 0x1bf59 0x1bef1 0xd532e 0xd588c 0xd49f5 0x49a2f 0x49c42 0x290fe 0x1b3fd 0x17d2f39 0x17d2c10 0x17ebda5 0x17ebb12 0x181cb46 0x181bed4 0x181bdab 0x17d1923 0x17d17a8 0x18e71 0x200d 0x1f35) libc++abi.dylib: terminate called throwing an exception

From my counting the range is within the bounds, I dont get why I am getting this error?

Any help would be appreciated.

Thanks

like image 251
Jacob Avatar asked Jun 21 '12 04:06

Jacob


4 Answers

Your NSMakeRange(start, end) should be NSMakeRange(start, end- start);

like image 136
user523234 Avatar answered Nov 11 '22 06:11

user523234


I think you have confusion in syntax of NSMakeRange. It is something like this

NSMakeRange(<#NSUInteger loc#>, <#NSUInteger len#>)

<#NSUInteger loc#>: It is the location from where you want to start picking or substring.

<#NSUInteger len#>: This is the length of your output or substring.

Example:

Mytest12test

Now I want to pick'12'

so:

NSString *t=@"Mytest12test";
NSString *x=[t substringWithRange:NSMakeRange(6, 2)] ;

In your code instead of length you are passing index of end character that is your mistake.

like image 33
Iducool Avatar answered Nov 11 '22 08:11

Iducool


I don't know why your are using this approach, but iOS provides a string function which separates a string with respect to another string and returns an array of the components. See the following example:

NSString * str = @"dadsada/2/dsadsa";
NSArray *listItems = [str componentsSeparatedByString:@"/"];
NSString *component = [listItems objectAtIndex:1];

Now your component string should have 2 store in it.

like image 2
Saleh Avatar answered Nov 11 '22 07:11

Saleh


When the compiler runs into this code...

else{   
    end = i + 1;
}

... in the last iteration of the loop, it sets the end variable to one more then the range of MYSTRING. This is why you are getting that error. To fix it, just do this:

else{   
    end = i;
}

Hope this helps!

P.S. Saleh's approach is a simpler way of accomplishing what you want

------UPDATE------

You should do it like this actually:

NSMutableArray *occurencesOfSlashes = [[NSMutableArray alloc] init];
char looking = '/';
for(int i=0; i < MYSTRING.length; i++){
if ([MYSTRING characterAtIndex:i] == looking) {
    [occurencesOfSlashes addObject:[NSNumber numberWithInt:i]];  
}
NSString *finalString = [MYSTRING substringWithRange:NSMakeRange([occurencesOfSlashes objectAtIndex:0],[occurencesOfSlashes objectAtIndex:1])];
like image 1
pasawaya Avatar answered Nov 11 '22 06:11

pasawaya