计算文件中的换行数

时间:2010-09-24 21:37:08

标签: objective-c cocoa cocoa-touch

使用objective-c / cocoa touch计算文件中换行符出现次数的最小代码是什么?

谢谢!

5 个答案:

答案 0 :(得分:3)

这应该让你前进:

NSString *fileContents = [NSString stringWithContentsOfFile:file encoding:encoding error:&error];
NSUInteger newlineCount = [fileContents numberOfOccurrencesOfString:@"\n"];

@interface NSString ()

- (NSUInteger)numberOfOccurrencesOfString:(NSString *)aString;
- (NSUInteger)numberOfOccurrencesOfChar:(char)aChar;

@end

@implementation NSString ()

- (NSUInteger)numberOfOccurrencesOfString:(NSString *)aString {
    NSRange range = [self rangeOfString:aString];
    NSUInteger length = [self length];
    NSUInteger count = 0;
    while (range.location != NSNotFound) {
        range = [self rangeOfString:aString options:0 range:NSMakeRange(range.location + range.length, length - range.location - range.length)];
        count++;
    }
    return count;
}

- (NSUInteger)numberOfOccurrencesOfChar:(char)aChar {
    const char *cString = [self cStringUsingEncoding:NSUTF8StringEncoding];
    NSUInteger stringLength = strlen(cString);
    NSUInteger count = 0;
    for (int i = 0; i < stringLength; i++) {
        if (cString[i] == aChar) {
            count++;
        }
    }
    return count;
}

@end

虽然“numberOfOccurrencesOfString:”不分配额外内存并支持字符串针,  “numberOfOccurrencesOfChar:”分配NSString的自动释放的c-string副本并搜索单个char。 “”

当你要求计算换行符(因此单个字符)时,我认为快速基准可能对这个特定目的有好处: 所以我拿了一个长度为2486813的测试字符串,总共包含78312'\ n'。 (我基本上采用了OSX的单词文件的变体)和... ...运行[testString numberOfOccurrencesOfString:@“\ n”] 100次:19.35s ...运行[testString numberOfOccurrencesOfChar:'\ n'] 100次:6.91s (设置:2.2GHz Core 2 Duo MacBook Pro,在单线程上运行)

[编辑:小虫修复;将第二个片段改为类别字符串方法。]

答案 1 :(得分:3)

其他两个答案都是正确的,但需要注意的是,他们需要将整个文件加载到内存中才能正常工作。

解决方法是使用NSFileHandle以递增方式加载文件。像这样:

NSFileHandle * file = [NSFileHandle fileHandleForReadingAtPath:pathToFile];
NSUInteger chunkSize = 1024;
NSData * chunk = [file readDataOfLength:chunkSize];
NSUInteger numberOfNewlines = 0;
while ([chunk length] > 0) {
  const unichar * bytes = (const unichar *)[chunk bytes];
  for (int index = 0; index < [chunk length]; ++index) {
    unichar character = (unichar)bytes[index];
    if ([[NSCharacterSet newlineCharacterSet] characterIsMember:character]) {
      numberOfNewlines++;
    }
  }
  chunk = [file readDataOfLength:chunkSize];
}

答案 2 :(得分:0)

您可以使用SubstringWithRange扫描字符串:

计算出现的次数。

答案 3 :(得分:0)

你说的最小吗?这会自动将此问题转换为代码高尔夫

FILE*f=fopen(path,"r");
int i,c;
while(1+c)i+=(c=fgetc(f))==10;
printf("%i",i);

(请不要实际使用此代码)

答案 4 :(得分:0)

如果你想留在Cocoa / CocoaTouch中,你可以使用NSRegularExpression:

NSString *theString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error];
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\n" options:NSRegularExpressionCaseInsensitive error:&error];
NSUInteger numLines = [regex numberOfMatchesInString:theString options:0 range:NSMakeRange(0, [theString length])] + 1;