سؤال

أنا أتطلع إلى ما يعادل ويندوز _wfopen() تحت نظام التشغيل Mac OS X.اي فكرة؟

أحتاج إلى هذا من أجل نقل مكتبة Windows التي تستخدم wchar* لواجهة الملف الخاصة به.نظرًا لأن المقصود منها أن تكون مكتبة مشتركة بين الأنظمة الأساسية، فلا أستطيع الاعتماد على كيفية حصول تطبيق العميل على مسار الملف وإعطائه إلى المكتبة.

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

المحلول

يمكن استخدام POSIX API في نظام التشغيل Mac OS X مع سلاسل UTF-8.لتحويل سلسلة wchar_t إلى UTF-8، من الممكن استخدام إطار عمل CoreFoundation من نظام التشغيل Mac OS X.

فيما يلي فئة ستغلف سلسلة UTF-8 التي تم إنشاؤها من سلسلة wchar_t.

class Utf8
{
public:
    Utf8(const wchar_t* wsz): m_utf8(NULL)
    {
        // OS X uses 32-bit wchar
        const int bytes = wcslen(wsz) * sizeof(wchar_t);
        // comp_bLittleEndian is in the lib I use in order to detect PowerPC/Intel
        CFStringEncoding encoding = comp_bLittleEndian ? kCFStringEncodingUTF32LE
                                                       : kCFStringEncodingUTF32BE;
        CFStringRef str = CFStringCreateWithBytesNoCopy(NULL, 
                                                       (const UInt8*)wsz, bytes, 
                                                        encoding, false, 
                                                        kCFAllocatorNull
                                                        );

        const int bytesUtf8 = CFStringGetMaximumSizeOfFileSystemRepresentation(str);
        m_utf8 = new char[bytesUtf8];
        CFStringGetFileSystemRepresentation(str, m_utf8, bytesUtf8);
        CFRelease(str);
    }   

    ~Utf8() 
    { 
        if( m_utf8 )
        {
            delete[] m_utf8;
        }
    }

public:
    operator const char*() const { return m_utf8; }

private:
    char* m_utf8;
};

الاستخدام:

const wchar_t wsz = L"Here is some Unicode content: éà€œæ";
const Utf8 utf8 = wsz;
FILE* file = fopen(utf8, "r");

سيعمل هذا على قراءة الملفات أو كتابتها.

نصائح أخرى

أنت فقط تريد فتح مؤشر ملف باستخدام مسار قد يحتوي على أحرف Unicode، أليس كذلك؟مجرد تمرير المسار في تمثيل نظام الملفات ل fopen.

  • إذا جاء المسار من أطر عمل Mac OS X (على سبيل المثال، لوحة مفتوحة سواء كانت Carbon أو Cocoa)، فلن تحتاج إلى إجراء أي تحويل عليها وستكون قادرًا على استخدامها كما هي.

  • إذا كنت تقوم بإنشاء جزء من المسار بنفسك، فيجب عليك إنشاء CFStringRef من المسار الخاص بك ثم الحصول على ذلك في تمثيل نظام الملفات لتمريره إلى واجهات برمجة تطبيقات POSIX مثل open أو fopen.

بشكل عام، لن تضطر إلى القيام بالكثير من ذلك بالنسبة لمعظم التطبيقات.على سبيل المثال، قد تحتوي العديد من التطبيقات على ملفات بيانات مساعدة مخزنة في دليل دعم التطبيقات الخاص بالمستخدم، ولكن طالما أن أسماء هذه الملفات هي ASCII، وتستخدم واجهات برمجة تطبيقات Mac OS X القياسية لتحديد موقع دليل دعم التطبيقات الخاص بالمستخدم، فلن تحتاج إلى للقيام بمجموعة من التحويلات المذعورة لمسار تم إنشاؤه باستخدام هذين المكونين.

تم التعديل للإضافة: أود أن أحذر بشدة ضد تحويل كل شيء بشكل تعسفي إلى UTF-8 باستخدام شيء من هذا القبيل wcstombs لأن ترميز نظام الملفات ليس بالضرورة مطابقًا لـ UTF-8 الذي تم إنشاؤه.يستخدم كل من نظامي التشغيل Mac OS X وWindows قواعد تحليل أساسية محددة (لكنها مختلفة) للتشفير المستخدم في مسارات نظام الملفات.

على سبيل المثال، يتعين عليهم أن يقرروا ما إذا كان سيتم تخزين "é" كوحدة رمز واحدة أو وحدتين (إما LATIN SMALL LETTER E WITH ACUTE أو LATIN SMALL LETTER E تليها COMBINING ACUTE ACCENT).سيؤدي ذلك إلى تسلسلين بايت مختلفين ومختلفين في الطول، ويعمل كل من نظامي التشغيل Mac OS X وWindows على تجنب وضع ملفات متعددة بنفس الاسم (كما يراها المستخدم) في نفس الدليل.

يمكن أن تصبح القواعد الخاصة بكيفية إجراء هذا التحليل الأساسي صعبة للغاية، لذا بدلاً من محاولة تنفيذها بنفسك، من الأفضل ترك الأمر للوظائف التي توفرها لك أطر النظام للقيام بالمهمة الثقيلة.

@JKP:

لا تقبل جميع الوظائف في MacOS X UTF8، ولكن قد تكون أسماء الملفات ومسارات الملفات UTF8، وبالتالي فإن جميع وظائف POSIX التي تتعامل مع الوصول إلى الملفات (فتح، fopen، stat، إلخ) تقبل UTF8.

يرى هنا.يقتبس:

كيف ينظر اسم الملف إلى مستوى API يعتمد على واجهة برمجة التطبيقات.أسماء ملفات واجهات برمجة تطبيقات Carbon الحالية كمجموعة من أحرف UTF-16 ؛تعاملها POSIX الخاصة بهم كمجموعة من UTF-8 ، وهذا هو السبب في أن UTF-8 يعمل بشكل جيد في المحطة.كيف يتم تخزينه على القرص يعتمد على تنسيق القرص ؛يستخدم HFS+ UTF-16 ، لكن هذا ليس مهمًا في معظم الحالات.

تتعامل بعض وظائف POSIX الأخرى مع UTF8 أيضًا.على سبيل المثالالوظائف التي تتعامل مع أسماء المستخدمين أو أسماء المجموعات أو كلمات مرور المستخدم تستخدم UTF8 لتخزين المعلومات (وبالتالي يمكن أن يكون اسم المستخدم يابانيًا وكلمة المرور الخاصة بك يمكن أن تكون صينية، لا توجد مشكلة).

ولكن لا يتعامل الجميع مع UTF8.على سبيل المثالبالنسبة لجميع وظائف السلسلة، فإن سلسلة UTF8 هي مجرد سلسلة C عادية والأحرف التي تزيد عن 126 ليس لها معنى خاص.إنهم لا يفهمون مفهوم البايتات المتعددة (الأحرف في لغة C) التي تشكل حرف Unicode واحد.تختلف كيفية تعامل واجهات برمجة التطبيقات الأخرى مع مؤشر char * الذي يتم تمريره إليها من API إلى API.ومع ذلك، كقاعدة عامة، يمكنك أن تقول:

إما أن تقبل الدالة فقط سلاسل C التي تحتوي على أحرف ASCII خالصة (فقط في النطاق من 0 إلى 126) أو أنها ستقبل UTF8.عادةً لا تسمح الوظائف بالأحرف التي تزيد عن 126 وتفسرها بأي ترميز آخر غير UTF8.إذا كان هذا هو الحال بالفعل، فسيتم توثيقه ومن ثم يجب أن تكون هناك طريقة لتمرير التشفير مع السلسلة.

إذا كنت تستخدم الكاكاو، فالأمر سهل إلى حد ما مع NSString.ما عليك سوى تحميل بيانات UTF16 باستخدام -initWithBytes:length:encoding:(أو ربما -initWithCString:encoding:) ثم احصل على إصدار UTF8 عن طريق استدعاء UTF8String على النتيجة.بعد ذلك، ما عليك سوى استدعاء fopen باستخدام سلسلة UTF8 الجديدة كمعلمة.

يمكنك بالتأكيد الاتصال بـ fopen باستخدام سلسلة UTF-8، بغض النظر عن اللغة - ولكن لا يمكنك المساعدة في لغة C++ على OSX - آسف.

لقد قرأت اسم الملف من ملف التكوين UTF8 من خلال com.wifstream (يستخدم wchar_t متعادل).

يختلف تطبيق Mac عن Linux وWindows.يقرأ wifstream كل بايت من الملف لفصل خلية wchar_t في المخزن المؤقت.إذن لدينا 3 بايتات فارغة يفتح يتطلب شار خيط.وبالتالي يمكن للمبرمج استخدامها com.wcstombs وظيفة لتحويل سلسلة أحرف واسعة إلى سلسلة متعددة البايت.

واجهة برمجة التطبيقات تدعم UTF8.لفهم أفضل، استخدم مراقب الذاكرة والمحرر السداسي لملفك.

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