سؤال

أحاول فتح ملف ، وأقرأ منه .. لكنني أواجه بعض المشكلات.

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 chars.

هل كانت مفيدة؟

المحلول

إذا كان هذا للهدف 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 Line سطر؟

IMO ، ليست هناك حاجة إلى النزول إلى وظائف Fileio على مستوى C إلا إذا كان لديك سبب وجيه للغاية للقيام بذلك (أي افتح ملفًا باستخدام ملف باستخدام O_SHLOCK أو شيء ما)

نصائح أخرى

يتم تخزين ملفك في UTF-16 (يونيكود). الحرف الأول في ملفك هو "L" ، وهو Code Point 0x4C. أول 4 بايت من ملفك FF FE 4C 00, ، وهي علامة بايت بايت (BOM) والحرف L المشفر في UTF-16 كبايت.

fgets ليس يونيكود ، لذلك يبحث عن شخصية الخط الجديد '\n', ، وهو بايت 0x0A. على الأرجح سيحدث هذا في أول بايت من خط يونيكود الجديد (البايتان 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) هو TREFINATOR C ، لذلك عندما تحاول طباعة هذا باستخدامه باستخدام printf, ، يتوقف عند الفرق الأولى ، وكل ما تراه هو \377\376L. \377\376 هو تمثيل ثماني البايتات FF FE.

الإصلاح لهذا هو تحويل الملف النصي الخاص بك إلى ترميز بايت واحد مثل ISO 8859-1 أو UTF-8. لاحظ أنه يجب أن لا يمكن ترميز الترميزات أحادية البايت (UTF-8) تشفير النطاق الكامل من أحرف Unicode ، لذلك إذا كنت بحاجة إلى Unicode ، فإنني أوصي بشدة باستخدام UTF-8. بدلاً من ذلك ، يمكنك تحويل البرنامج الخاص بك إلى أن يكون unicode ، ولكن بعد ذلك لم يعد بإمكانك استخدام الكثير من وظائف المكتبة القياسية (مثل fgets و printf) ، وتحتاج إلى استخدام wchar_t في كل مكان بدلاً من char.

إذا كنت لا تمانع في قراءة كل ملف ، فيمكنك فعل شيء مثل هذا:

NSData* myData = [NSData dataWithContentsOfFile:myFileWithPath];

ثم افعل ما تريد مع البيانات من هناك. سوف تحصل على شيء إذا لم يكن الملف موجودًا.

إذا كنت تفترض بيانات النص (سلسلة) في هذا الملف ، يمكنك بالإضافة إلى ذلك القيام بشيء من هذا القبيل ثم تحليله كـ NSString:

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

نظرًا لأنك ذكرت أنك جديد نسبيًا على الهدف-C ، يمكنك البحث عن nsstrings بشكل جيد إلى حد ما. الق نظرة هنا لمزيد من المعلومات حول هذا.

أردت هذا أيضًا وفكرت "افعل هذا بدلاً من ذلك" لم يجيب على السؤال ، إليك مثال عمل أدناه. احذر من أن 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);
 printf("%s test\n");

أنت لا تمرر السلسلة إلى printf. محاولة

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

أيضًا ، إذا كان ملفك يحتوي على سطر يزيد طوله عن 200 حرف ، فستقرأ Fgets 200 حرف في WAH - ثم أضف NUL إلى النهاية ، والتي ستكون خارج نهاية WAH (نظرًا لأنك أعلنت أنها 200 حرف) وستقوم تدوس على شيء عشوائي ، وسيكون سلوك برنامجك غير محدد وقد يشعل النار على قطتك.

حصلت سايكلريل. التوسع في هذه الإجابة ، إليك طريقة أخرى (في رأيي ، أبسط) لتحويل تلك البيانات إلى سلسلة:

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

هذا يعلن عن NSString جديد مباشرة باستخدام NSDATA المحدد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top