6

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

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

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

知道为什么吗?

完整代码:

#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 个字符。

4

6 回答 6

15

如果这是针对 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];

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

如何逐行从 NSFileHandle 读取数据?

O_SHLOCKIMO,除非您有非常非常好的理由这样做(即,使用或其他方式打开文件),否则无需下拉到 C 级 fileIO 函数

于 2010-11-17T20:04:38.513 回答
6

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

fgets不支持 Unicode,因此它正在寻找换行符'\n',即字节 0x0A。这很可能发生在 Unicode 换行符的第一个字节(两个字节0A 00)上,但也可能发生在许多其他非换行符上,例如 U+010A(带点的拉丁大写字母 A)或Gurmukhi 或古吉拉特语脚本(U+0A00 到 U+0AFF)。

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

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

于 2010-11-17T20:41:17.453 回答
3

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

NSData* myData = [NSData dataWithContentsOfFile:myFileWithPath];

然后对那里的数据做任何你想做的事情。如果文件不存在,您将得到 nil。

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

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

由于您提到您对objective-c 比较陌生,因此您可以很好地搜索NSStrings。在这里查看更多信息。

于 2010-11-17T19:57:38.900 回答
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);
于 2013-04-28T00:01:03.017 回答
0

斯莱克雷尔明白了。扩展该答案,这是将数据转换为字符串的另一种(在我看来,更简单)的方法:

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

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

于 2011-03-23T01:59:56.573 回答
0
 printf("%s test\n");

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

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

此外,如果您的文件包含超过 200 个字符的行,fgets 会将 200 个字符读入 wah - 然后在末尾添加 NUL,这将超出 wah 的末尾(因为您声明它是 200 个字符)并且将随意践踏一些东西,你的程序的行为将是不确定的,并且可能会着火你的猫。

于 2010-11-17T19:57:22.530 回答