2010-01-22 98 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]); 
} 

**编辑:**感谢以下彼得的答案,我发现我的扫描仪被卡在*字符后面。我在循环中添加了这一行:

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

现在它的工作方式应该如此。

+0

你不需要*分隔符。您可以扫描普通换行符(现在您的循环已修复)。 – 2010-01-22 12:12:06

回答

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:@“*”]',但失败了。大概卡在*角色。我想到了你的答案,并添加了上面的代码。现在它可以工作。谢谢。 – 2010-01-22 09:10:34

0

我认为这种情况是错误的。按照String Programming Guide,它应该是这样的:

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

只要还有什么要扫描,'isAtEnd'不会返回YES。因此,这是一个无限循环,因为它永远不会扫过第一行的末尾。看到我的答案。 – 2010-01-22 08:24:25

+0

感谢您的意见。 – 2010-01-22 09:00:49