scanUpToCharactersFromSet останавливается после одного цикла - PullRequest
3 голосов
/ 22 января 2010

Я пытаюсь получить содержимое файла CSV в массив. Когда я делал это раньше, у меня была одна запись на строку, и я использовал символ новой строки с scanUpToCharactersFromSet:intoString:, передавая newlineCharacterSet в качестве набора символов:

while ([lineScanner scanUpToCharactersFromSet:[NSCharacterSet newlineCharacterSet] 
                                   intoString:&line])

Теперь я работаю с файлом, в котором многие записи содержат символы новой строки. Я попытался добавить уникальный символ в конец каждой записи (символ *), но мой цикл запускается только один раз. Есть ли что-то, что делает разрыв цикла while, о котором я не знаю? Вот код, который я сейчас использую:

NSError *error;
NSString *data = [[NSString alloc] initWithContentsOfFile:[[self delegate] filePath] encoding:NSUTF8StringEncoding error:&error];
NSScanner *lineScanner = [NSScanner scannerWithString:data];
NSString *line = nil;

// Start parsing the CSV file
while ([lineScanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"*"]
                    intoString:&line]) {
    NSArray *elements = [line componentsSeparatedByString:@","];
    NSLog("Name: %@", [elements objectAtIndex:1]);
}

** Редактировать: ** Благодаря приведенному ниже ответу Питера я обнаружил, что мой сканер застрял за * символом. Я добавил эту строку в цикл:

[lineScanner scanCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"*"] intoString:NULL];

и теперь работает как надо.

Ответы [ 2 ]

2 голосов
/ 22 января 2010

Давайте пройдем один проход за раз:

  1. First:

    while ([lineScanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:[NSCharacterSet newlineCharacterSet]] intoString:&line]) {
    

    Сканер помещает все до разрыва строки в line. Это продвигается до новой строки.

  2. Второе:

    while ([lineScanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:[NSCharacterSet newlineCharacterSet]] intoString:&line]) {
    

    Сканер уже находится на разрыве строки, поэтому он не сканирует символы. Как задокументировано , поскольку он не сканировал никаких символов, он возвращает NO. Ваш цикл завершается.

Решение состоит в том, чтобы сканировать разрыв строки в конце цикла, чтобы пройти сканер. Вы можете передать NULL в качестве выходного параметра, предполагая, что вам все равно, каким был разрыв строки.

Это правильное поведение: если вам все равно, какие символы вы отсканировали, это позволит вам получить их. Это будет сложнее, если NSScanner автоматически отсканирует символы.

0 голосов
/ 22 января 2010

Я думаю, что в то время как условие неверно. В соответствии с String Programming Guide , это должно быть что-то вроде:

while ([theScanner isAtEnd] == NO) {
    [lineScanner scanUpToCharactersFromSet:[NSCharacterSet characterSetWithCharactersInString:@"*"] intoString:&line]
    // ...
}
...