Roland Rabien
Roland Rabien

Reputation: 8836

How do I get each line from an NSString?

If I have an NSString with a text file in it, how do I get an NSArray of NSString with each NSString containing a line of the file.

In 10.5 I did this:

NSArray* lines = [str componentsSeparatedByCharactersInSet: [NSCharacterSet newlineCharacterSet]];

But that doesn't work in 10.4, and my program needs to work in 10.4.

As well, it needs to work with \r, \n and \r\n line endings.

Upvotes: 8

Views: 12794

Answers (6)

James Eichele
James Eichele

Reputation: 119184

The following code is straight from Apple's documentation regarding paragraphs and line breaks:

unsigned length = [string length];
unsigned paraStart = 0, paraEnd = 0, contentsEnd = 0;
NSMutableArray *array = [NSMutableArray array];
NSRange currentRange;
while (paraEnd < length)
{
    [string getParagraphStart:&paraStart end:&paraEnd
    contentsEnd:&contentsEnd forRange:NSMakeRange(paraEnd, 0)];
    currentRange = NSMakeRange(paraStart, contentsEnd - paraStart);
    [array addObject:[string substringWithRange:currentRange]];
}

I'm not 100% sure if it will work with 10.4

Upvotes: 10

Heng-Cheong Leong
Heng-Cheong Leong

Reputation: 864

I'll first replace all \r with \n, then replace all \n\n with \n, and then do a componentsSeparatedByString:@"\n".

Upvotes: 5

siburb
siburb

Reputation: 5017

You can also do enumerateSubstringsInRange: with the NSStringEnumerationByLines and/or NSStringEnumerationByParagraphs options.

The benefit of doing it that way is that you get the NSRange of each substring, and can also set the initial range of the string to enumerate.

[myString enumerateSubstringsInRange:NSMakeRange(0, myString.length) options:NSStringEnumerationByLines | NSStringEnumerationByParagraphs usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {

}];

Upvotes: 0

Rich Catalano
Rich Catalano

Reputation: 1147

Straight from a project of mine:

 NSString * fileContents = [NSString stringWithContentsOfFile:pathToFile encoding:NSUTF8StringEncoding error:nil];
 NSMutableArray * fileLines = [[NSMutableArray alloc] initWithArray:[fileContents componentsSeparatedByString:@"\r\n"] copyItems: YES];

I'm not sure how to make it it automatically work with any type of line ending in 10.4.

Upvotes: 3

Vineet Choudhary
Vineet Choudhary

Reputation: 7632

Enumerates all the lines in a string using enumerateLinesUsingBlock:

[yourString enumerateLinesUsingBlock:^(NSString * _Nonnull line, BOOL * _Nonnull stop) {
    //line
}];

Declaration

- (void)enumerateLinesUsingBlock:(void (^)(NSString *line,
                                   BOOL *stop))block

Parameters

block The block executed for the enumeration.

The block takes two arguments:

line The current line of the string being enumerated. The line contains just the contents of the line, without the line terminators.

stop A reference to a Boolean value that the block can use to stop the enumeration by setting *stop = YES; it should not touch *stop otherwise.

Availability Available in OS 10.6 and iOS 4.0 and later.

Upvotes: 8

John Safranek
John Safranek

Reputation: 743

According to the NSString class reference, the NSString message componentsSeparatedByCharactersInSet: is available in OS X 10.5 or later. You need to use componentsSeparatedByString:.

Upvotes: 2

Related Questions