打开文件并从文件Objective-c中读取

时间:2010-11-17 19:55:09

标签: objective-c fgets

我正在尝试打开一个文件,并从中读取..但我遇到了一些问题。

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

这打印:\ 377 \ 376N测试而不是我文件的任何内容。

任何想法为什么?

完整代码:

#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;

}

test242.txt不包含超过200个字符。

6 个答案:

答案 0 :(得分:13)

如果这是针对Objective-C的,为什么不这样做:

使用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
}

或使用NSString:

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

或者如果您需要逐行阅读:

How to read data from NSFileHandle line by line?

IMO,没有必要下载到C级fileIO函数,除非你有非常好的理由(即使用O_SHLOCK或其他东西打开文件)

答案 1 :(得分:6)

您的文件存储在UTF-16(Unicode)中。文件中的第一个字符是“L”,即代码点0x4C。文件的前4个字节是FF FE 4C 00,它是字节顺序标记(BOM),字母L以UTF-16编码为两个字节。

fgets不支持Unicode,因此它正在寻找换行符'\n',即字节0x0A。很可能这会发生在Unicode换行符的第一个字节(两个字节0A 00)上,但它也可能发生在许多其他非换行符上,例如U + 010A(拉丁文大写字母A上面有点) )或Gurmukhi或Gujarati剧本中的任何内容(U + 0A00到U + 0AFF)。

但是,在任何情况下,最终在缓冲区wah中的数据都有很多嵌入的空值,看起来像FF FE 4C 00 47 00 4F 00 4F 00 0A 00。 NUL(0x00)是C字符串终止符,因此当您尝试使用printf打印出来时,它会在第一个空值处停止,您看到的只是\377\376L\377\376是字节FF FE的八进制表示。

解决此问题的方法是将文本文件转换为单字节编码,例如ISO 8859-1或UTF-8。请注意,必须使用单字节编码(UTF-8除外)不能编码所有Unicode字符,因此如果您需要Unicode,我强烈建议您使用UTF-8。或者,您可以将程序转换为支持Unicode的,但是您不能再使用许多标准库函数(例如fgetsprintf),并且需要使用{{1无处不在wchar_t

答案 2 :(得分:2)

如果您不介意阅读所有文件,可以执行以下操作:

NSData* myData = [NSData dataWithContentsOfFile:myFileWithPath];

然后根据那里的数据做任何你喜欢的事情。如果文件不存在,您将获得nil。

如果您在此文件中假设文本(字符串)数据,您可以另外执行类似的操作,然后将其解析为NSString:

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

由于你提到你对objective-c相对较新,你可以很好地搜索NSStrings。有关详细信息,请查看here

答案 3 :(得分:1)

我也想要这个,并且认为“这样做”没有回答这个问题,下面是一个工作示例。请注意fgets读取\ n分隔符并附加到您的文本。

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);

答案 4 :(得分:0)

 printf("%s test\n");

您没有将字符串传递给printf。尝试

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

另外,如果你的文件包含超过200个字符长的行,fgets会将200个字符读入wah - 然后在末尾添加一个NUL,这将在wah结束时(因为你声明它是200个字符)并且会随意践踏某些东西,并且你的程序的行为将是不确定的,可能会引起你的猫的攻击。<​​/ p>

答案 5 :(得分:0)

Slycrel得到了它。扩展这个答案,这是另一种(在我看来,更简单)将数据转换为字符串的方式:

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

这直接使用指定的NSData声明一个新的NSString。