Question

I'm trying to open a file, and read from it.. but I'm having some issues.

FILE *libFile = fopen("/Users/pineapple/Desktop/finalproj/test242.txt","r");
char wah[200];
fgets(wah, 200, libFile);
printf("%s test\n", wah);

this prints: \377\376N test rather than any of the contents of my file.

any idea why?

complete code:

#import <Cocoa/Cocoa.h>
#import <stdio.h>

int main(int argc, char *argv[])
{
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

FILE *libFile = fopen("/Users/pineapple/Desktop/finalproj/test242.txt","r");
if(libFile){
char wah[200];
fgets(wah, 200, libFile);
printf("%s test\n", wah);
    }
[pool drain];
return 0;

}

And the test242.txt doesn't contain more than 200 chars.

Was it helpful?

Solution

If this is for Objective-C, why not do something like:

use NSFileHandle:

NSString * path = @"/Users/pineapple/Desktop/finalproj/test242.txt";
NSFileHandle * fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
NSData * buffer = nil;
while ((buffer = [fileHandle readDataOfLength:1024])) {
  //do something with the buffer
}

or use NSString:

NSString * fileContents = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];

or if you need to read it line-by-line:

How to read data from NSFileHandle line by line?

IMO, there's no need to drop down to the C-level fileIO functions unless you have a very very very good reason for doing so (ie, open a file using O_SHLOCK or something)

OTHER TIPS

Your file is stored in UTF-16 (Unicode). The first character in your file is "L", which is code point 0x4C. The first 4 bytes of your file are FF FE 4C 00, which are a byte-order mark (BOM) and the letter L encoded in UTF-16 as two bytes.

fgets is not Unicode-aware, so it's looking for the newline character '\n', which is the byte 0x0A. Most likely this will happen on the first byte of a Unicode newline (the two bytes 0A 00), but it could also happen on plenty of other non-newline characters such as U+010A (LATIN CAPITAL LETTER A WITH DOT ABOVE) or anything in the Gurmukhi or Gujarati scripts (U+0A00 to U+0AFF).

In any case, though, the data that's ending up in the buffer wah has lots of embedded nulls and looks something like FF FE 4C 00 47 00 4F 00 4F 00 0A 00. NUL (0x00) is the C string terminator, so when you attempt to print this out using printf, it stops at the first null, and all you see is \377\376L. \377\376 is the octal representation of the bytes FF FE.

The fix for this is to convert your text file to a single-byte encoding such as ISO 8859-1 or UTF-8. Note that must single-byte encodings (UTF-8 excepted) cannot encode the full range of Unicode characters, so if you need Unicode, I strongly recommend using UTF-8. Alternatively, you can convert your program to be Unicode-aware, but then you can no longer use a lot of standard library functions (such as fgets and printf), and you need to use wchar_t everywhere in place of char.

If you don't mind reading all of a file you can do something like this:

NSData* myData = [NSData dataWithContentsOfFile:myFileWithPath];

and then do whatever you'd like with the data from there. You will get nil if the file doesn't exist.

If you are assuming text (string) data in this file you can additionally do something like this and then parse it as a NSString:

NSString* myString = [[NSString alloc] initWithBytes:[myData bytes] length:[myData length] encoding:NSUTF8StringEncoding];

Since you mentioned you are relatively new to objective-c you can search NSStrings fairly well. Have a look here for more info on this.

I wanted this as well and thought "do this instead" did not answer the question, here is a working example below. Beware that fgets reads the \n delimiter and appends to your text.

NSString * fName = [[NSBundle mainBundle] pathForResource:@"Sample" ofType:@"txt"];
FILE *fileHandle = fopen([fName UTF8String],"r");
char space[1024];
while (fgets(space, 1024, fileHandle) != NULL)
{
    NSLog(@"space = %s", space);
}

fclose(fileHandle);
 printf("%s test\n");

You're not passing the string to printf. Try

 printf("%s test\n", wah);

Also, if your file contains a line more than 200 characters long, fgets will read 200 characters into wah - then add a NUL to the end, which will be off the end of wah (since you declared it to be 200 characters) and will trample over something random, and the behaviour of your program will be undefined and may set fire to your cat.

Slycrel's got it. Expanding on that answer, here is another (in my opinion, simpler) way of turning that data into a string:

NSString *myFileString = [[NSString alloc] initWithData:someData encoding:NSUTF8StringEncoding];

This declares a new NSString directly using the NSData specified.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top