2010-01-22 5 views
3

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

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]); 
} 

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

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

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

+0

Вам не нужен разделитель *. Вы можете сканировать для простых разрывов строк просто отлично (теперь, когда ваш цикл исправлен). –

ответ

2

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

  1. Первое:

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

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

  2. Второе:

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

    Сканер уже на изломе линии, поэтому он не сканирует никаких символов. As documented, так как он не проверял никаких символов, он возвращает NO. Ваша петля завершается.

Решение заключается в scan the line break в конце цикла, чтобы получить сканер мимо него. Вы можете передать NULL для выходного параметра, предполагая, что вам все равно, что это за разрыв строки.

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

+0

Спасибо за ответ Питер. Цикл, который использовал '[NSCharacterSet newlineCharacterSet]', работал нормально с CSV-файлом с одной записью на строку. С помощью многострочной записи CSV я помещал * в конец каждой записи и пытался «[NSCharacterSet characterSetWithCharactersInString: @» * "]', но это не удалось. Предположительно застрял в * персонаже. Я подумал о вашем ответе и добавил код выше. Теперь это работает. Благодарю. –

0

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

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

Пока еще что-то еще предстоит отсканировать, 'isAtEnd' не вернет' YES'. Таким образом, это бесконечный цикл, поскольку он никогда не просматривает конец первой строки. См. Мой ответ. –

+0

Спасибо за точку. –

Смежные вопросы