Использование C ++ Builder XE5 (bcc32) в Windows 7.
Я пытаюсь открыть файл, имя файла которого содержит широкий символ. Фактическое имя файла, с которым я тестирую C:\bΛx\foo.txt
, Не-ASCII символ там есть U + 039B.
У меня есть это имя файла правильно хранится в std::wstring
, Тем не менее, пытаясь:
std::ifstream f( filename.c_str() );
не удается открыть файл.
Конечно, в стандарте C ++ fopen
только занимает char *
, Тем не менее, реализация Dinkumware C ++ RTL имеет перегрузку, принимающую 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, но, конечно, я не могу использовать iostreams C ++.
Есть ли способ использовать std::ifstream
открыть файл с U + 039B или другими такими символами в имени файла?
Обратите внимание, что с помощью std::wifstream
тоже не работает (он все еще пытается открыть UTF-8 версию имени файла).
Если я открою файл с помощью
_wfopen( filename.c_str(), L"r" )
тогда все хорошо, и я могу прочитать файл, используя функции ввода-вывода C, но, конечно, я не могу использовать iostreams C ++.
Я не вижу этого «конечно». Ваша проблема сводится к созданию iostreams streambuf
из FILE*
, Говард Хиннант ответил Вот что нет никакого стандарта, предусмотренного стандартом, но реализация streambuf
класс на вершине FILE*
это довольно просто. Он даже упоминает некоторый код, который, по его мнению, будет хорошей отправной точкой.
Обратите внимание, что это имеет смысл только для текстового файла. iostreams и бинарные файлы не уживаются; есть слой кодировки символов и ios_base::binary
не выключает это.