2010-11-17 37 views
6

Tôi đang cố mở một tập tin và đọc từ nó .. nhưng tôi đang gặp một số vấn đề.Mở tập tin và đọc từ tập tin Objective-c

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

bản in này: \ 377 \ 376N kiểm tra thay vì bất kỳ nội dung nào trong tệp của tôi.

bất kỳ ý tưởng nào tại sao?

mã hoàn chỉnh:

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

} 

Và test242.txt không chứa hơn 200 ký tự.

Trả lời

13

Nếu đây là cho Objective-C, tại sao không làm một cái gì đó như:

sử dụng 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 
} 

hoặc sử dụng NSString:

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

hoặc nếu bạn cần phải đọc nó từng dòng:

How to read data from NSFileHandle line by line?

IMO, không có nhu cầu để thả xuống vào thư mục C cấp chức năng fileIO trừ khi bạn có một lý do rất rất rất tốt để làm như vậy (ví dụ, mở một tập tin sử dụng O_SHLOCK hoặc một cái gì đó)

+0

Mục tiêu là đọc văn bản từ tệp, từng chữ một. Tôi mới vào Objective-C, và (ít nhất là) tôi biết cách quản lý các tệp văn bản bằng cách sử dụng các hàm c. –

+2

Điều này là chính xác. Nếu tệp không nhất thiết chứa dữ liệu chuỗi (tức là byte nguyên) sử dụng đối tượng NSData với hàm tạo dataWithContentsOfFile của nó và bạn sẽ không phải lo lắng về việc giải thích tự động chuỗi mã hóa của NSString. –

0
printf("%s test\n"); 

Bạn không chuyển chuỗi đó tới printf. Hãy thử

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

Ngoài ra, nếu tập tin của bạn có chứa một đường dài hơn 200 ký tự, fgets sẽ đọc 200 ký tự vào wah - sau đó thêm một NUL đến cuối, mà sẽ được ra khỏi cuối của wah (kể từ khi bạn tuyên bố nó sẽ là 200 ký tự) và sẽ chà đạp lên một cái gì đó ngẫu nhiên, và hành vi của chương trình của bạn sẽ không xác định và có thể gây cháy cho con mèo của bạn.

+0

Tôi phải thực hiện lỗi này trong khi cố sửa lỗi. Tôi đã chỉnh sửa thành \t printf ("% s yeh \ n", wah); và nó có cùng một vấn đề –

+0

Vui lòng đăng chính xác, đầy đủ, mã mà bạn đang thử nghiệm. –

+0

Tệp của bạn có tồn tại không? Bạn không kiểm tra thành công của fopen –

3

Nếu bạn không nhớ đọc tất cả của một tập tin bạn có thể làm một cái gì đó như thế này:

NSData* myData = [NSData dataWithContentsOfFile:myFileWithPath]; 

và sau đó làm bất cứ điều gì bạn muốn với các dữ liệu từ đó. Bạn sẽ nhận được nil nếu tệp không tồn tại.

Nếu bạn đang giả định văn bản (string) dữ liệu trong tập tin này, bạn bổ sung có thể làm một cái gì đó như thế này và sau đó phân tích nó như một NSString:

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

Kể từ khi bạn nói bạn là tương đối mới để Objective-C bạn có thể tìm kiếm NSStrings khá tốt. Hãy xem here để biết thêm thông tin về điều này.

+0

Tôi phải thực hiện lỗi này trong khi cố khắc phục lỗi đó. Tôi đã chỉnh sửa thành printf ("% s yeh \ n", wah); và nó có cùng một vấn đề –

+0

paul là chính xác, có rất ít chúng tôi có thể làm mà không cần thêm thông tin. Bạn có chắc chắn rằng tệp của bạn tồn tại và các fgets đang đọc dữ liệu? Hãy thử thiết lập wah để một cái gì đó đầu tiên để đảm bảo rằng rác không chỉ là dữ liệu uninitialized, somethhing như thế này: char wah [200] = "hello"; – slycrel

+0

Tôi đã thử khởi tạo một thứ gì đó, nó sẽ in thử nghiệm \ 377 \ 376H khi chương trình chạy. Ngoài ra, tôi hiện đang kiểm tra và tệp chắc chắn tồn tại. –

6

tập tin của bạn được lưu trữ trong UTF-16 (Unicode). Ký tự đầu tiên trong tệp của bạn là "L", là mã 0x4C. 4 byte đầu tiên của tệp của bạn là FF FE 4C 00, là một dấu thứ tự byte (BOM) và chữ L được mã hóa bằng UTF-16 dưới dạng hai byte.

fgets không nhận dạng Unicode, vì vậy, tìm kiếm ký tự dòng mới '\n', là byte 0x0A.Nhiều khả năng điều này sẽ xảy ra trên byte đầu tiên của một dòng mới Unicode (hai byte 0A 00), nhưng nó cũng có thể xảy ra trên nhiều ký tự không phải là dòng mới như U + 010A (LATIN CAPITAL LETTER A WITH DOT ABOVE) hoặc bất kỳ thứ gì trong các kịch bản Gurmukhi hoặc Gujarati (U + 0A00 đến U + 0AFF).

Trong mọi trường hợp, dữ liệu kết thúc trong bộ đệm wah có nhiều giá trị được nhúng và trông giống như FF FE 4C 00 47 00 4F 00 4F 00 0A 00. NUL (0x00) là bộ kết thúc chuỗi C, vì vậy khi bạn cố gắng in ra bằng cách sử dụng printf, nó dừng ở giá trị đầu tiên, và tất cả những gì bạn thấy là \377\376L. \377\376 là biểu diễn bát phân của các byte FF FE.

Khắc phục sự cố này là chuyển đổi tệp văn bản của bạn thành mã hóa một byte chẳng hạn như ISO 8859-1 hoặc UTF-8. Lưu ý rằng phải mã hóa một byte (UTF-8 ngoại trừ) không thể mã hóa đầy đủ các ký tự Unicode, vì vậy nếu bạn cần Unicode, tôi khuyên bạn nên sử dụng UTF-8. Ngoài ra, bạn có thể chuyển đổi chương trình thành nhận dạng Unicode, nhưng sau đó bạn không thể sử dụng nhiều chức năng thư viện chuẩn (chẳng hạn như fgetsprintf), và bạn cần sử dụng wchar_t ở mọi nơi thay cho char.

+0

... hoặc chỉ sử dụng một cái gì đó hiểu UTF16 nguyên bản, giống như 'NSString' –

+1

Ah Dave, bạn trẻ ngày nay với bạn mã hóa ưa thích, khung cấp cao và bây giờ thậm chí đánh bại âm nhạc, bạn sẽ làm hỏng thế giới đẹp của chúng tôi .. . –

0

Slycrel đã nhận được. Mở rộng trên câu trả lời rằng, đây là một (theo ý kiến ​​của tôi, đơn giản hơn) cách chuyển dữ liệu đó vào một chuỗi:

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

này tuyên bố một NSString mới trực tiếp bằng cách sử dụng NSData quy định.

1

Tôi muốn điều này là tốt và nghĩ rằng "làm điều này thay thế" đã không trả lời câu hỏi, đây là một ví dụ làm việc dưới đây. Cẩn thận rằng fgets đọc \ n dấu phân cách và nối thêm vào văn bản của bạ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);