In VS-2005 hielt die Unicode und UTF-8 Unterstützung Einzug in die CRT und damit auch in die MFC. Jochen und ich haben dazu gebloggt.
Leider ist die Implementierung nicht fehlerfrei. Wenn man eine UTF-8 Datei mit ccs=UNICODE öffnet dann liefert ftell zum Teil auch negative Werte. Das ftell nicht die exakte Position in der Datei liefert ist dokumentiert, nur sollte es mit dem Wert zumindest möglich sein wieder fseek aufzurufen um an eine alte Dateiposition zurück zu gelangen.
Das ist mit der jetzigen Implementierung nicht möglich.
Ein Sample dazu ist schnell gebaut:
int _tmain()
{
FILE *file = NULL;
if (_tfopen_s(&file,_T("Test.txt"),_T("rt") _T(", ccs=UNICODE")))
return -1;
TCHAR szBuffer[_MAX_PATH];
while (_fgetts(szBuffer,_countof(szBuffer),file))
{
int iPos = static_cast(ftell(file));
_tprintf(_T("%d\n"),iPos);
_ASSERTE(fseek(file,iPos,SEEK_SET)==0);
}
fclose(file);
return 0;
}
Ein entsprechendes Sample kann man hier herunterladen.
Der Fehler betrifft natürlich auch die MFC mit CStdioFile und GetPosition!
Hintergrund:
Ich kam auf den Fehler, weil wir ein Programm benutzen, dass sich bestimmte Dateipositionen merkte um einen Datenimport bei einer bestimmten Bedingung, ab einer definierten Stelle, neu aufnehmen zu können. Bisher hatten wir hier nur pure ASCII Dateien erlaubt, jetzt wollten wir auch UTF-8 Dateien unterstützen.
Sicher man kann auch alles im Speicher zwischenhalten, aber wenn es eine simple Dateiposition ist das Ganze so weitaus Ressourcen schonender.
Soweit ich das übersehen kann, betrifft der Fehler alle VS-Versionen ab VS-2005. Ein entsprechende Bug wurde von mir schon vor längerer Zeit auf Connect geöffnet. Getan hat sich bisher noch nichts:
https://connect.microsoft.com/VisualStudio/feedback/details/591030/ftell-returns-negative-value-for-utf-8-files-opened-with-textmode-and-ccs
Hallo Martin,
erstaunlich aber wahr.
Bin auch grad auf diesen Bloedsinn gestossen.
Gibt es eine brauchbare Umgehungsloesung?