我是Xcode的新手,并尝试解析CSV文件(以百万计)。我已经阅读了很多贡献而且我正在管理它,但是当我的NSScanner拦截一个空字段时我遇到了问题:“Field_A,Field_B ,, Field_D”。我想这是因为它默认忽略了空格,或者在这种情况下根本没有空格。
字符串是:
“个人”, “2011-01-01”, “个人”, “香烟” ,, 4.60, “现金”, “”,
我尝试使用scanLocation调试它:
2011-04-22 15:57:32.414 Spending[42015:a0f] Before while...scan location is:0
2011-04-22 15:57:32.414 Spending[42015:a0f] Account: "Personal" - scan location is:10
2011-04-22 15:57:32.415 Spending[42015:a0f] Date: "2011-01-01" - scan location is:23
2011-04-22 15:57:32.415 Spending[42015:a0f] Category: "Personal" - scan location is:34
2011-04-22 15:57:32.416 Spending[42015:a0f] Subcategory: "Cigarettes" - scan location is:47
2011-04-22 15:57:32.416 Spending[42015:a0f] Income: 4.600000 - scan location is:53
2011-04-22 15:57:32.416 Spending[42015:a0f] Expense: 0.000000 - scan location is:53
2011-04-22 15:57:32.417 Spending[42015:a0f] Payment: "Cash" - scan location is:60
2011-04-22 15:57:32.417 Spending[42015:a0f] Note: "" - scan location is:63
正如你所看到的那样,即使费用字段也没有价值(应该是4.60)。
以下是相关的代码:
NSScanner *scanner = [NSScanner scannerWithString:fileString];
[scanner setCharactersToBeSkipped: [NSCharacterSet characterSetWithCharactersInString:@"\n, "]];
NSString *account, *date, *category, *subcategory, *payment, *note;
float income, expense;
// Set up data delimiter using comma
NSCharacterSet *commaSet;
commaSet = [NSCharacterSet characterSetWithCharactersInString:@","];
NSLog (@"Before while...scan location is:%d\n", scanner.scanLocation);
[scanner scanUpToCharactersFromSet:commaSet intoString:&account];
NSLog(@"Account: %@ - scan location is:%d\n",account, scanner.scanLocation);
[scanner scanUpToCharactersFromSet:commaSet intoString:&date];
NSLog(@"Date: %@ - scan location is:%d\n",date, scanner.scanLocation);
[scanner scanUpToCharactersFromSet:commaSet intoString:&category];
NSLog(@"Category: %@ - scan location is:%d\n",category, scanner.scanLocation);
[scanner scanUpToCharactersFromSet:commaSet intoString:&subcategory];
NSLog(@"Subcategory: %@ - scan location is:%d\n",subcategory, scanner.scanLocation);
[scanner scanFloat:&income];
NSLog(@"Income: %f - scan location is:%d\n",income, scanner.scanLocation);
[scanner scanFloat:&expense];
NSLog(@"Expense: %f - scan location is:%d\n",expense, scanner.scanLocation);
[scanner scanUpToCharactersFromSet:commaSet intoString:&payment];
NSLog(@"Payment: %@ - scan location is:%d\n",payment, scanner.scanLocation);
[scanner scanUpToCharactersFromSet:commaSet intoString:¬e];
NSLog(@"Note: %@\n - scan location is:%d",note, scanner.scanLocation);
我试过仔细查看NSScanner Class Reference,但是无法理解?你有什么?
谢谢,Fabrizio。
答案 0 :(得分:2)
在Objective-C中解析CSV?听起来很熟悉:
https://github.com/davedelong/CHCSVParser
免责声明:我写了。 :)
对于你正在做的事情,你可以直接获取文件并通过类似+[NSArray arrayWithContentsOfCSVFile:encoding:error:]
方法的方式运行,或者你可以将它读成字符串并执行以下操作:
NSString *csv = @"\"Personal\",\"2011-01-01\",\"Personal\",\"Cigarettes\",,4.60,\"Cash\",\"\",";
NSLog(@"%@", [csv CSVComponents]);
哪些日志:
2011-04-22 09:51:16.651 CHCSVParser[2658:903] (
(
Personal,
"2011-01-01",
Personal,
Cigarettes,
"",
"4.60",
Cash,
""
)
)
(请注意,这是[{1}} NSArray
NSArrays
的{{1}}
如果您担心内存增加,那么您也可以直接使用NSStrings
并通过代理接收信息。它的运作方式与CHCSVParser
的工作原理非常相似。
答案 1 :(得分:0)
查看this article on CSV扫描仪。
这是另一个article
Dave DeLong的解决方案也很有效。
底线:CSV似乎微不足道,但如果你想要优雅地处理任何向你抛出的CSV,那真的不是这样。
答案 2 :(得分:0)
扫描仪看不到您的空字段的原因是您告诉它跳过逗号。您使用一组3个字符调用了setCharactersToBeSkipped:
当您再询问扫描仪“scanFloat”时,它会越过任何可跳过的字符,直到达到十进制数字。这就是跳过空字段的方式。
如果要捕获空字段,请从要跳过的字符集中删除逗号。然后,每当扫描函数找到一个空字段时,它将返回NO。发生这种情况时,您可能需要手动增加扫描位置。