2014-09-28 3 views
0

У меня есть строка @" ILL WILL KILLS ", и я использую NSScanner's scanUpToString:intoString:, чтобы найти каждое появление «ILL». Если это точно, это будет NSLog 4, 9 и 14.В чем преимущества символов NSScannerToBeSkipped?

Моя строка начинается с 4 пробелов, которые, как я понимаю, являются членами NSScanner по умолчанию charactersToBeSkipped NSCharacterSet. Если я установил charactersToBeSkipped в nil, как в примере ниже, то этот код точно найдет 3 появления «ILL».

NSScanner* scanner = [NSScanner scannerWithString:@" ILL WILL KILLS "] ; 
scanner.charactersToBeSkipped = nil ; 
NSString* scannedCharacters ; 
while (TRUE) { 
    BOOL didScanUnignoredCharacters = [scanner scanUpToString:@"ILL" intoString:&scannedCharacters] ; 
    if (scanner.isAtEnd) { 
     break ; 
    } 
    NSLog(@"Found match at index: %tu", scanner.scanLocation) ; 
    // Since stopString "ILL" is 3 characters long, advance scanLocation by 3 to find the next "ILL". 
    scanner.scanLocation += 3 ; 
} 

Однако, если я не аннулирует по умолчанию charactersToBeSkipped, вот что происходит:

  • scanner инициализируется scanLocation == 0.
  • scanUpToString выполняет в первый раз, он «смотрит мимо» 4 пустых места и «видит» ILL по индексу 4, поэтому он сразу останавливается. scanLocation по-прежнему 0.
  • Я считаю, что я нашел матч, и я увеличиваем scanLocation на 3.
  • scanUpToString выполняется в течение 2-й раз, он «смотрит мимо» 1 пустое пространство и «видит» ILL с индексом 4, поэтому он сразу же останавливается. scanLocation по-прежнему 3.

Для меня, это конструктивный недостаток, что scanner остановился на scanLocation == 0 в первый раз, так как я ожидал, что он остановится на scanLocation == 4. Если вы считаете, что приведенный выше код можно переписать точно NSLog 4, 9 и 14 без настроек 10 - nil, то , пожалуйста,, покажите мне, как. На данный момент я считаю, что charactersToBeSkipped существует только для того, чтобы сделать NSScanners более сложным в использовании.

ответ

0

На данный момент, мое мнение таково, что charactersToBeSkipped существует только сделать NSScanner s более трудно использовать.

Тогда вы не очень изобретательны. «Преимущество» charactersToBeSkipped - это ... дождаться ... пропустить символы. Например, если у вас есть строка, такая как @" 8 9 10 ", вы можете сканировать эти три целых числа, используя -scanInt: три раза. Вам не нужно заботиться о точном количестве пробелов, которые отделяют их.

Учитывая задание, которое вы описываете, вы просто ищете экземпляры строки в строке, NSScanner, вероятно, не самый подходящий инструмент. Вероятно, вы захотите использовать -[NSString rangeOfString:options:range:].

Документы для -scanUpToString:intoString: достаточно ясны. Если stopString является первой строкой в ​​приемнике (с учетом того, что charactersToBeSkipped будет пропущен), тогда метод возвращает NO, то есть он ничего не сканирует. Следовательно, местоположение сканирования не будет изменено.

Возвращаемое значение указывает на успех или неудачу. Если строка останова следующая (игнорирование символов, которые нужно пропустить), тогда нет ничего, чтобы сканировать «до» стоп-строки; сканер уже находится в стоп-строке, поэтому метод выходит из строя.

+0

Вы правы, что 'rangeOfString', вероятно, лучший инструмент для поиска определенных строк. Раньше я раньше не использовал 'scanInt', но я вижу, как он хорошо работает с по умолчанию' charactersToBeSkipped' и не работает с 'nil'' charactersToBeSkipped'. –