[英]Using ifstream when filename contains wide characters
Using C++Builder XE5 (bcc32) in Windows 7. 在Windows 7中使用C ++ Builder XE5(bcc32)。
I am trying to open a file whose filename contains a wide character. 我正在尝试打开一个文件名包含宽字符的文件。 The actual filename I'm testing with is C:\\bΛx\\foo.txt
. 我正在测试的实际文件名是C:\\bΛx\\foo.txt
。 The non-ASCII character there is U+039B . 那里的非ASCII字符是U + 039B。
I have this filename stored correctly in a std::wstring
. 我已将此文件名正确存储在std::wstring
。 However, trying: 但是,尝试:
std::ifstream f( filename.c_str() );
fails to open the file. 无法打开文件。
Of course, in Standard C++ fopen
only takes char *
. 当然,在标准C ++中, fopen
仅使用char *
。 However, the Dinkumware C++ RTL implementation has an overload accepting wchar_t *
. 但是,Dinkumware C ++ RTL实现具有接受wchar_t *
的重载。 Unfortunately the implementation of that overload in ...\\Embarcadero\\RAD Studio\\12.0\\source\\cpprtl\\Source\\dinkumware\\source\\fiopen.cpp
does not call _wfopen
. 不幸的是,在...\\Embarcadero\\RAD Studio\\12.0\\source\\cpprtl\\Source\\dinkumware\\source\\fiopen.cpp
中实现该重载不会调用_wfopen
。 Instead it uses wcstombs
to convert the string to UTF-8 and then calls fopen
. 而是使用wcstombs
将字符串转换为UTF-8,然后调用fopen
。
Checking the source for fopen
, it calls the narrow version of an underlying function ___topen
which ultimately passes the UTF-8 string to CreateFile
. 检查源代码是否存在fopen
,它会调用基础函数___topen
的窄版,该函数最终将UTF-8字符串传递给CreateFile
。
When I inspect the attempt to open the file using Sysinternals Process Monitor, it shows that it did attempt to open the file with a UTF-8 file string, and the operating system rejected this with the result NAME COLLISION
. 当我检查使用Sysinternals Process Monitor打开文件的尝试时,它表明它确实尝试使用UTF-8文件字符串打开文件,并且操作系统拒绝了该结果,结果为NAME COLLISION
。
If I open the file using _wfopen( filename.c_str(), L"r" )
then all is well and I can read the file using CI/O functions, but I can't use C++ iostreams of course. 如果我使用_wfopen( filename.c_str(), L"r" )
打开文件_wfopen( filename.c_str(), L"r" )
那么一切都很好,我可以使用CI / O函数读取文件,但是我当然不能使用C ++ iostream。
Is there any way to use std::ifstream
to open a file with U+039B or other such characters in the filename? 有什么方法可以使用std::ifstream
打开带有U + 039B或文件名中其他类似字符的文件?
Note that using std::wifstream
doesn't work either (it still tries to open the UTF-8 version of the filename). 请注意,使用std::wifstream
也不起作用(它仍然尝试打开文件名的UTF-8版本)。
If I open the file using
_wfopen( filename.c_str(), L"r" )
then all is well and I can read the file using CI/O functions, but I can't use C++ iostreams of course. 如果我使用_wfopen( filename.c_str(), L"r" )
打开文件_wfopen( filename.c_str(), L"r" )
那么一切都很好,我可以使用CI / O函数读取文件,但是我当然不能使用C ++ iostream。
I don't see that "of course". 我看不到“当然”。 Your problem is reduced to making an iostreams streambuf
from a FILE*
. 您的问题已减少到从FILE*
制作iostreams streambuf
。 Howard Hinnant answered here that there's no method provided by the Standard, but implementing a streambuf
-derived class on top of FILE*
is pretty straightforward. Howard Hinnant 在此处回答说,标准没有提供任何方法,但是在FILE*
之上实现streambuf
派生的类非常简单。 He even mentions some code that he feels would be a good starting point. 他甚至提到一些他认为是一个很好的起点的代码。
Note that this only makes sense for a text file. 请注意,这仅对文本文件有意义。 iostreams and binary files do not get along; iostream和二进制文件不相处; there's a character encoding layer and ios_base::binary
does not turn that off. 有一个字符编码层, ios_base::binary
不会将其关闭。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.