0

I'm trying to to read lines one by one from an external txt file (about 180kb) using Objective-C. I have found this piece of code here on SO. The way I understand it this code will put every line in an element right?

- (IBAction)start:(id)sender; {
    NSString *fh = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:NULL];
    for (NSArray *line in [fh componentsSeparatedByString:@"\n"]) {
        NSLog(@"output= %@",line[5]);
    }
}

I try to check if it is working by printing a line to my output but nothing happens, what am I doing wrong here?

Thanks,

Update: I made the suggested changes and as it turnout fh is indeed nil. If I make fh a string containing a piece of the text file (including a few \n) it works fine. I checked the file path but that seems allright, So the question now would be how come fh = nil?

NSString *fh = [NSString stringWithContentsOfFile:@"file:///Users/Mubanga/Documents/Blender/rough2.txt" encoding:NSUTF8StringEncoding error:nil];
if([fh length] == 0) {
    NSLog(@"fh=nil");
}
for (NSString *line in [fh componentsSeparatedByString:@"\n"]) {
    NSLog(@"output= %@",line);
    }

}
Peter Hosey
  • 95,783
  • 15
  • 211
  • 370
Mubanga
  • 43
  • 7
  • First of all, verify that fh is not nil. – Martin R Jan 30 '14 at 14:59
  • @MartinR you were right, fh turned out te be nil. How can I prevent this from happening? – Mubanga Jan 30 '14 at 15:28
  • You might also want to not use `fh` as the name of a variable that does not contain an NSFileHandle. Since it contains a string, I would name it `string`, `str`, or `fileContents` or something like that. – Peter Hosey Jan 30 '14 at 23:26

3 Answers3

3

The loop should be:

for (NSString *line in [fh componentsSeparatedByString:@"\n"]) {
    NSLog(@"output= %@",line);
}

(line will be an NSString and the output should be line, not line[5]).

trojanfoe
  • 120,358
  • 21
  • 212
  • 242
  • Indeed. `componentsSeparatedByString:` returns an array, and the `for` loop *iterates through the objects in the array*. The objects in the array are strings—each string being one of the lines from the original string. – Peter Hosey Jan 30 '14 at 23:28
3

In addition to the required changes from @trojanfoe's answer, your fh is nil because the path is wrong. stringWithContentsOfFile: expects a simple path, not a file-URL. It should be:

 NSString *fh = [NSString stringWithContentsOfFile:@"/Users/Mubanga/Documents/Blender/rough2.txt" encoding:NSUTF8StringEncoding error:nil];

Generally, you should use the error parameter:

NSError *error;
NSString *fh = [NSString stringWithContentsOfFile:@"/Users/Mubanga/Documents/Blender/rough2.txt"
                                         encoding:NSUTF8StringEncoding
                                            error:&error];
if (fh == nil) {
    NSLog(@"Could not read file: %@", error);
} else {
    // ...
}
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
1

I would do the character input by hand using native C calls. Just read() into a char[] buffer until you hit a newline, then process the buffer. No I won't write the code for you, check out the still-relevant K&R.

QED
  • 9,803
  • 7
  • 50
  • 87
  • I have to agree. When it comes to parsing files I still prefer standard C. There is nothing wrong with using C as Objective-C is just a superset of C. – Freddy Jan 30 '14 at 16:11
  • 1
    And yet K&R lived in the ASCII age where all users spoke English, or else. This is no longer the case and `NSString` is better equipped to deal with non-latin characters than plain C is. – trojanfoe Jan 31 '14 at 01:24