Frage

Ich suche nach dem Äquivalent von Windows _wfopen() unter Mac OS X.Irgendeine Idee?

Ich benötige dies, um eine Windows-Bibliothek zu portieren, die verwendet wchar* für seine Dateischnittstelle.Da es sich um eine plattformübergreifende Bibliothek handeln soll, kann ich mich nicht darauf verlassen, wie die Clientanwendung den Dateipfad erhält und an die Bibliothek weitergibt.

War es hilfreich?

Lösung

Die POSIX-API in Mac OS X kann mit UTF-8-Zeichenfolgen verwendet werden.Um einen wchar_t-String in UTF-8 zu konvertieren, ist es möglich, das CoreFoundation-Framework von Mac OS X zu verwenden.

Hier ist eine Klasse, die eine UTF-8-generierte Zeichenfolge aus einer wchar_t-Zeichenfolge umschließ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;
};

Verwendung:

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

Dies funktioniert zum Lesen oder Schreiben von Dateien.

Andere Tipps

Sie möchten einfach nur ein Dateihandle über einen Pfad öffnen, der möglicherweise Unicode-Zeichen enthält, oder?Geben Sie einfach den Pfad weiter Dateisystemdarstellung Zu fopen.

  • Wenn der Pfad von den Standard-Frameworks von Mac OS

  • Wenn Sie einen Teil des Pfads selbst generieren, sollten Sie eine CFStringRef aus Ihrem Pfad erstellen und diese dann in einer Dateisystemdarstellung abrufen, um sie an POSIX-APIs wie z. B. zu übergeben open oder fopen.

Im Allgemeinen müssen Sie für die meisten Anwendungen nicht viel davon tun.Beispielsweise können in vielen Anwendungen Hilfsdatendateien im Anwendungsunterstützungsverzeichnis des Benutzers gespeichert sein. Solange die Namen dieser Dateien jedoch ASCII sind und Sie Standard-APIs von Mac OS X verwenden, um das Anwendungsunterstützungsverzeichnis des Benutzers zu finden, ist dies nicht erforderlich eine Menge paranoider Konvertierungen eines mit diesen beiden Komponenten konstruierten Pfads durchzuführen.

Bearbeitet, um Folgendes hinzuzufügen: Ich würde dringend warnen gegen willkürlich alles in UTF-8 konvertieren, indem man so etwas verwendet wcstombs weil die Dateisystemkodierung nicht unbedingt mit der generierten UTF-8 identisch ist.Sowohl Mac OS

Sie müssen beispielsweise entscheiden, ob „é“ als eine oder zwei Codeeinheiten (entweder) gespeichert wird LATIN SMALL LETTER E WITH ACUTE oder LATIN SMALL LETTER E gefolgt von COMBINING ACUTE ACCENT).Dies führt zu zwei unterschiedlichen – und unterschiedlich langen – Bytesequenzen, und sowohl Mac OS

Die Regeln für die Durchführung dieser kanonischen Zerlegung können ziemlich schwierig sein. Anstatt also zu versuchen, sie selbst zu implementieren, überlassen Sie die schwere Arbeit am besten den Funktionen, die Ihnen die System-Frameworks zur Verfügung gestellt haben.

@JKP:

Nicht alle Funktionen in MacOS

Sehen Hier.Zitat:

Wie ein Dateiname auf die API -Ebene schaut, hängt von der API ab.Aktuelle Kohlenstoff-APIs behandeln Dateinamen als Array von UTF-16-Zeichen;Possixen verarbeiten sie als eine Reihe von UTF-8, weshalb UTF-8 im Terminal gut funktioniert.Wie es auf der Festplatte gespeichert wird, hängt vom Festplattenformat ab.HFS+ verwendet UTF-16, aber das ist in den meisten Fällen nicht wichtig.

Einige andere POSIX-Funktionen verarbeiten ebenfalls UTF8.Z.B.Funktionen, die sich mit Benutzernamen, Gruppennamen oder Benutzerkennwörtern befassen, verwenden UTF8 zum Speichern der Informationen (ein Benutzername kann also japanisch sein und Ihr Passwort kann chinesisch sein, kein Problem).

Aber nicht alle beherrschen UTF8.Z.B.Für alle String-Funktionen ist ein UTF8-String nur ein normaler C-String und Zeichen über 126 haben keine besondere Bedeutung.Sie verstehen das Konzept nicht, dass mehrere Bytes (Zeichen in C) ein einzelnes Unicode-Zeichen bilden.Wie andere APIs mit dem an sie übergebenen char * -Zeiger umgehen, ist von API zu API unterschiedlich.Als Faustregel gilt jedoch:

Entweder akzeptiert die Funktion nur C-Strings mit reinen ASCII-Zeichen (nur im Bereich 0 bis 126) oder sie akzeptiert UTF8.Normalerweise erlauben Funktionen keine Zeichen über 126 und interpretieren sie in einer anderen Kodierung als UTF8.Wenn dies wirklich der Fall war, wird es dokumentiert und dann muss es eine Möglichkeit geben, die Codierung zusammen mit der Zeichenfolge zu übergeben.

Wenn Sie Cocoa verwenden, ist es mit NSString ziemlich einfach.Laden Sie einfach die UTF16-Daten mit -initWithBytes:length:encoding:(oder vielleicht -initWithCString:encoding:) und erhalten Sie dann eine UTF8-Version, indem Sie UTF8String für das Ergebnis aufrufen.Rufen Sie dann einfach fopen mit Ihrer neuen UTF8-Zeichenfolge als Parameter auf.

Sie können fopen definitiv mit einer UTF-8-Zeichenfolge aufrufen, unabhängig von der Sprache – mit C++ unter OSX kann ich allerdings nicht helfen – sorry.

Ich habe den Dateinamen aus der UTF8-Konfigurationsdatei gelesen wifstream (es benutzt wchar_t Puffer).

Die Mac-Implementierung unterscheidet sich von Linux und Windows.wifstream liest jedes Byte aus der Datei in eine separate wchar_t-Zelle im Puffer.Wir haben also 3 leere Bytes offen erfordert verkohlen Zeichenfolge.So können Programmierer verwenden wcstombs Funktion zum Konvertieren einer breiten Zeichenfolge in eine Mehrbyte-Zeichenfolge.

Die API unterstützt UTF8.Zum besseren Verständnis verwenden Sie den Memory Watcher und den Hex-Editor für Ihre Datei.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top