NSScanner поведение - PullRequest
       13

NSScanner поведение

1 голос
/ 20 февраля 2012

Я очень новичок в разработке для iOS. Я пытаюсь проанализировать простой CSV-файл, который имеет около 10 строк, разделенных запятыми. Я использую приведенный ниже код, но не могу понять, почему NSScanner при разборе полей (полей в коде ниже) не переходит к следующей строке после запятой. Я должен выполнить строку

[fields scanCharactersFromSet:fieldCharSet intoString:nil];

чтобы он прошел через разделитель. Однако мне не нужно делать то же самое для строк - NSScanner автоматически устанавливает позицию на следующей строке после новой строки. В обоих случаях я использую один и тот же метод - [lines scanUpToCharactersFromSet: intoString] Есть что-то, чего я не понимаю?

Вот тестовый файл, который я пытаюсь проанализировать:

Name,Location,Number,Units
A,AA,4,mm
B,BB,3.5,km
C,CC,10.2,mi
D,DD,2,mm
E,EE,6,in
F,FF,2.8,m
G,GG,3.7,km
H,HH,4.3,mm
I,II,4,km

Вот мой код:

-(void)parseFile {
    NSCharacterSet *lineCharSet = [NSCharacterSet newlineCharacterSet];
    NSCharacterSet *fieldCharSet = [NSCharacterSet characterSetWithCharactersInString:self.separator];
    // import the file

    NSStringEncoding *encoding = nil;
    NSError *error = nil;
    NSString *data = [[NSString alloc] initWithContentsOfURL:self.absoluteURL usedEncoding:encoding error:&error];
    NSString *line,*field;


    NSScanner *lines = [NSScanner scannerWithString:data]; 
    while (![lines isAtEnd]) {

        [lines scanUpToCharactersFromSet:lineCharSet intoString:&line];//automatically sets to next line - why?



        NSLog(@"%@\n",line);

        NSScanner *fields = [NSScanner scannerWithString:line];

        while (![fields isAtEnd]) {

            [fields scanUpToCharactersFromSet:fieldCharSet intoString:&field];

            [fields scanCharactersFromSet:fieldCharSet intoString:nil]; //have to do this otherwise will not go to next symbol

            NSLog(@"%@\n", field);

        }
    }
}

1 Ответ

2 голосов
/ 20 февраля 2012

Так работает NSScanner. Когда вы используете scanUpToCharactersFromSet:intoString:, он сканирует символы до , но не включает символов в наборе. Если вы хотите, чтобы он проходил мимо персонажей в наборе, у вас есть два варианта:

  1. Сделайте так, чтобы он сканировал эти символы. Вы делаете это сейчас, используя scanCharactersFromSet:intoString:. Еще один способ сделать это - [fields scanString:self.separator intoString:nil].

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

Стандартный набор символов, который должен быть пропущен сканером, включает перевод строки. Вот почему ваш внешний сканер пропускает новую строку.

Вы можете сделать это полностью, используя componentsSeparatedByString: вместо NSScanner. Пример:

-(void)parseFile {
    NSString *data = [[NSString alloc] initWithContentsOfURL:self.absoluteURL usedEncoding:encoding error:&error];

    for (NSString *line in [data componentsSeparatedByString:@"\n"]) {
        if (line.length == 0)
            continue;

        NSLog(@"line: %@", line);

        for (NSString *field in [line componentsSeparatedByString:self.separator]) {
            NSLog(@"    field: %@", field);
        }
    }
}
...