Die CRT der VC-2005 hat eine perfekte Unterstützung für Unicode Dateien im UTF-8 und UTF-16 Little Endian Format.
Wollte man bisher Unicode Dateien lesen, so mussten diese mit _wfopen(…,L“rb“) geöffnet werden und entsprechende Leseoperationen mussten folgen. Um Unicode und ANSI Dateien zu unterscheiden schrieb man selbst entsprechenden Code, der nach einer BOM (Byte Order Mark) schaut. Beim Schreiben hatte man auch selbst darauf zu achten die BOM entsprechend zu setzen.
Ziemlich unbemerkt (auch von mir 🙂 ), hat die CRT hier eine entscheidene Erweiterung erfahren. Mit dem folgenden Code lässt sich gezielt jede Datei entsprechend öffnen und lesen, sofern Sie über eine korrekte BOM verfügt, bzw. auch eine Datei zum Schreiben öffnen die mit der entsprechenden BOM versehen wird.
FILE *pFile = _tfopen(_T(„myfile.txt“),_T(„rt, ccs=UNICODE“));
Ist die Datei eine ANSI Datei ohne BOM, wird sie entsprechend geöffnet. Unicode Dateien im Typ UTF-8 und UTF-16 little endian werden an der entsprechenden BOM erkannt und entsprechend gelesen.
Über ccs=UTF-8 bzw. ccs=UTF-16LE lässt sich auch gezielt eine entsprechende Unicode Datei ohne BOM öffnen. Eine vorhandene BOM überschreibt allerdings die beim Öffnen angegebenen Formatierung. Fein!
Leider hinkt die MFC diesen wirklich tollen Funktionen der CRT hinterher. Weder die MFC 8.0 aus VS-2005 noch die neue Orcas Version (Stand Beta1) verfügt über eine neue Version der CStdioFile, die diese Funktionen der CRT abbildet.
Glücklicherweise gibt es einen entsprechenden CStdioFile(FILE *) Konstruktor. Dadurch ist es möglich, einfach eine Datei mit _tfopen zu öffnen und den Stream einfach an ein CStdioFile Objekt zu koppeln.
Einziger Schönheitsfehler: CStdioFile::Close muss explizit in diesem Fall aufgerufen werden, d. h. Close wird nicht durch den Destruktor aufgerufen.
Für den MFC Kenner: m_bCloseOnDelete ist FALSE und leider protected. Dieses Flag verhindert, dass Close auch durch den Destruktor aufgerufen wird.
Den von Dir beschriebenen „Schönheitsfehler“ habe ich für mich behoben, indem ich mir für eben diesen Zweck eine Klasse von CStdioFile abgeleitet habe.
In meiner Open Funktion habe ich dann ja Zugriff auf m_bCloseOnDelete. 😉