Разбор строки в разделах с помощью NSScanner

Я пытаюсь разобрать строку в таком формате:

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

и т.д

Количество дат, количество групп и связанное с ними место проведения могут варьироваться. Я использую код на основе примера в нижней части эта страница.

Я использую этот фрагмент кода (я пропустил биты внизу, поскольку они не имеют значения, но да, я закрываю циклы и т. д.):

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

В настоящее время первая дата анализируется и выводится на консоль, а также первое место проведения и группа этой даты. "Завершенное сканирование" никогда не печатается. Я боролся с этим в течение нескольких часов, и я не уверен, что делать сейчас. У меня есть ощущение, что я не понимаю внутреннюю работу NSScanner, и, вероятно, есть другой способ решить эту проблему. Может быть, мне нужен второй сканер?


person Grant    schedule 05.07.2011    source источник
comment
Вторая петля? Вы не показали нам вторую петлю здесь. То, что вы сделали до сих пор, кажется прекрасным.   -  person jtbandes    schedule 05.07.2011
comment
Извините, я имел в виду второй цикл if. Таким образом, есть цикл while, цикл if (if1) внутри него, а затем цикл if внутри этого цикла (if2). В настоящее время сканер застревает внутри if1 (он никогда не выходит) и входит в if2 только один раз, когда он должен делать это несколько раз.   -  person Grant    schedule 05.07.2011
comment
Оператор if не является циклом. Застрять там невозможно. Можете ли вы сказать нам, что именно выводится на печать и что содержат tempDate, tempBands и tempVenue?   -  person jtbandes    schedule 05.07.2011
comment
Я имел в виду цикл while (цикл while действительно содержит только if1. Я изменил if2, чтобы напечатать строку, содержащую tempBand, tempDate и tempVenue вместе. Пока программа печатает первую дату (tempDate) сама по себе, затем первую запись под эту дату.   -  person Grant    schedule 05.07.2011
comment
Я отредактировал свой оригинальный пост на основе ваших отзывов. Спасибо за помощь до сих пор, я не смог скопировать и вставить свой код, а затем отредактировать его, поэтому я пропустил некоторые разделы кода и сделал неясным для вас и для себя, что на самом деле происходит...   -  person Grant    schedule 05.07.2011


Ответы (1)


После первого раунда цикла while сканер находится сразу после "venue1.". Следующий раунд цикла начинается со сканирования звездочки, что завершается ошибкой (возвращается НЕТ), поскольку следующим (не пробельным) символом является тире. Таким образом, тело оператора if не выполняется, и позиция сканера не перемещается дальше, что приводит к бесконечному циклу.

person omz    schedule 05.07.2011
comment
Большое спасибо! Я решил эту проблему с помощью простого оператора goto (я постоянно слышу о том, как плохо их использовать, но мой код на самом деле имеет больше смысла, когда я использую его сейчас. Проблема решена. - person Grant; 05.07.2011