我正在尝试打开一个文件,并从中读取..但我遇到了一些问题。
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个字符。
答案 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的,但是您不能再使用许多标准库函数(例如fgets
和printf
),并且需要使用{{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。