С помощью C++ Builder xe5 (bcc32) в Windows 7.Использование ifstream, когда имя файла содержит широкие символы
Я пытаюсь открыть файл, имя файла содержит широкий характер. Фактическое имя файла, с которым я тестирую, - C:\bΛx\foo.txt
. Символ, не являющийся ASCII, имеет U + 039B.
У меня есть это имя файла, сохраненное правильно в std::wstring
. Однако, пытается:
std::ifstream f(filename.c_str());
не может открыть файл.
Конечно, в стандартном C++ fopen
принимает только char *
. Однако реализация RTL Dinkumware C++ имеет перегрузку, принимающую wchar_t *
. К сожалению, реализация этой перегрузки в ...\Embarcadero\RAD Studio\12.0\source\cpprtl\Source\dinkumware\source\fiopen.cpp
не вызывает _wfopen
. Вместо этого он использует wcstombs
для преобразования строки в UTF-8, а затем вызывает fopen
.
Проверка источника на fopen
, он вызывает узкую версию базовой функции ___topen
, которая в конечном итоге передает строку UTF-8 в CreateFile
.
Когда я проверяю попытку открыть файл с помощью Sysinternals Process Monitor, он показывает, что он попытался открыть файл с помощью строки файла UTF-8, а операционная система отклонила это с результатом NAME COLLISION
.
Если я открою файл, используя _wfopen(filename.c_str(), L"r")
, тогда все будет хорошо, и я могу прочитать файл с помощью функций C I/O, но я не могу использовать C++ iostreams, конечно.
Есть ли способ использовать std::ifstream
, чтобы открыть файл с U + 039B или другими такими символами в имени файла?
Обратите внимание, что использование std::wifstream
не работает (оно все еще пытается открыть версию файла UTF-8).
Это явно ошибка в Dinkumware в Windows. Windows не поддерживает UTF-8 в большинстве своих API. Вы должны отправить отчет авторам Dinkumware. И версия 'wchar_t *' 'ifstream', и' wifstream', должны использовать исходное значение as-is с '_wfopen()', а не преобразовывать в UTF-8 и вызывать 'fopen()'. Это может работать на других платформах, но не на Windows. –
Это было сообщено Embarcadero 2 года назад, оно все еще открыто. См. [QC# 111462] (http://qc.embarcadero.com/wc/qcmain.aspx?d=111462). –
@RemyLebeau источник Dinkum имеет параметр '# ifdef', который будет делать все вызовы через' _wfopen', но (насколько я мог видеть на моем быстром просмотре) он не может заставить 'fstream (char *)' перейти к 'fopen', а также' fstream (wchar_t *) 'перейти к' _wfopen' в той же сборке. Я не уверен, поддерживает ли C++ Builder попытку перестроить свою упакованную версию Dinkum для настройки '_wfopen'? –