【问题标题】:NSScanner behaviorNSScanner 行为
【发布时间】:2012-02-19 22:09:26
【问题描述】:

我对 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);

        }
    }
}

【问题讨论】:

    标签: iphone objective-c ios ipad nsscanner


    【解决方案1】:

    这就是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);
            }
        }
    }
    

    【讨论】:

    • 罗布,谢谢您的回答。但是,为什么当我在行上使用它时它会自动将扫描位置增加到下一行。
    • 罗布,感谢您的回复。 NSScanner 的默认行为是跳过换行符和空格。我错过了这部分。 - rp
    • @RXP 你应该检查这个答案是否正确,以奖励抢劫给你的帮助
    • 如果您想计算行数,这是最好的方法。但是,“\n”可能会也可能不会给出您期望的结果,请阅读 Apple 的 String Programming Guide: Line and Paragraph Separator Characters
    猜你喜欢
    • 2023-03-13
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-19
    • 2015-12-27
    • 2011-09-13
    相关资源
    最近更新 更多