Grant
Grant

Reputation: 23

Parsing string in sections with NSScanner

I am trying to parse a string with a format like this:

*date1:
- band1.1 @ venue1.1.
- band1.2 @ venue1.2.
*date2:
- band 2.1 @ venue2.1.
- band 2.2 @ venue2.2.

etc

The number of dates and the number of bands and the associated venue can vary. I am using code based on the example at the bottom of this page.

I am using this snippet of code (I left out the bits at the bottom as they are irrelevant, but yes, I do close the loops etc.):

 NSScanner *scanner1 = [NSScanner scannerWithString:contents];
NSCharacterSet *colon = [NSCharacterSet characterSetWithCharactersInString:@":"];
NSCharacterSet *at = [NSCharacterSet characterSetWithCharactersInString:@"@"];
NSCharacterSet *dot = [NSCharacterSet characterSetWithCharactersInString:@"."];
NSLog(@"scanner starting");

while ([scanner1 isAtEnd] == NO) {
    if ([scanner1 scanString:@"*" intoString:NULL] && [scanner1 scanUpToCharactersFromSet:colon intoString:&tempDate] && [scanner1 scanString:@":" intoString:NULL]) 
    {
        NSLog(@"%@", tempDate);
        if ([scanner1 scanString:@"-" intoString:NULL] && [scanner1 scanUpToCharactersFromSet:at intoString:&tempBands] && [scanner1 scanString:@"@" intoString:NULL] && [scanner1 scanUpToCharactersFromSet:dot intoString:&tempVenue]
            &&[scanner1 scanString:@"." intoString:NULL]) 
        {
            NSLog(@"%@ %@", tempBands, tempVenue);
        }
    }
}   NSLog(@"ended scanning"); 

Currently, the first date is parsed and printed to the console, and the first venue and band of that date are printed. "ended scanning" is never printed. I have been battling this for hours and I am unsure of what to do now. I have a feeling that I do not understand the inner workings of NSScanner and there is probably a different way to tackle this problem. Maybe I need a second scanner?

Upvotes: 0

Views: 659

Answers (1)

omz
omz

Reputation: 53561

After the first round of the while loop, the scanner's position is right after "venue1.". The next round of the loop starts with scanning an asterisk, which fails (returns NO) because the next (non-whitespace) character is a dash. Therefore, the body of the if statement isn't executed and the scanner's position is not advanced any further, resulting in an infinite loop.

Upvotes: 1

Related Questions