Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 当文件名包含宽字符时使用ifstream_C++_Windows_Unicode_Ifstream_C++builder Xe5 - Fatal编程技术网

C++ 当文件名包含宽字符时使用ifstream

C++ 当文件名包含宽字符时使用ifstream,c++,windows,unicode,ifstream,c++builder-xe5,C++,Windows,Unicode,Ifstream,C++builder Xe5,在Windows7中使用C++Builder XE5(bcc32) 我试图打开一个文件名包含宽字符的文件。我测试的实际文件名是C:\b∧x\foo.txt。那里的非ASCII字符是U+039B 我已将此文件名正确存储在std::wstring中。然而,尝试: std::ifstream f( filename.c_str() ); 无法打开该文件 当然,在标准C++ +Cult> fOpen< 中只使用 char *。但是,DcCuMuffC++ C++ RTL实现有一个超载接受 WCARGY

在Windows7中使用C++Builder XE5(bcc32)

我试图打开一个文件名包含宽字符的文件。我测试的实际文件名是
C:\b∧x\foo.txt
。那里的非ASCII字符是U+039B

我已将此文件名正确存储在
std::wstring
中。然而,尝试:

std::ifstream f( filename.c_str() );
无法打开该文件

<>当然,在标准C++ +Cult> fOpen< <代码>中只使用<代码> char *<代码>。但是,DcCuMuffC++ C++ RTL实现有一个超载接受<代码> WCARGYT*<代码>。不幸的是,
..\Embarcadero\RAD Studio\12.0\source\cpprtl\source\dinkumware\source\fiopen.cpp
中的重载实现没有调用
\wfopen
。相反,它使用
wcstombs
将字符串转换为UTF-8,然后调用
fopen

检查源代码中的
fopen
,它调用底层函数
\uuuuu-topen
的狭义版本,该函数最终将UTF-8字符串传递给
CreateFile

当我检查使用Sysinternals Process Monitor打开文件的尝试时,它显示它确实尝试使用UTF-8文件字符串打开文件,并且操作系统拒绝了此操作,结果是
名称冲突

如果我使用<代码>文件>(文件名:CyScript(),L“R”)< /C> >打开文件,那么所有的都是好的,我可以使用C/IO函数读取文件,但是我当然不能使用C++ IoSoW。 是否有任何方法可以使用
std::ifstream
打开文件名中包含U+039B或其他类似字符的文件

请注意,使用
std::wifstream
也不起作用(它仍然尝试打开文件名的UTF-8版本)

如果我使用<代码>文件>(文件名:CyScript(),L“R”)< /C> >打开文件,那么所有的都是好的,我可以使用C/IO函数读取文件,但是我当然不能使用C++ IoSoW。 我不认为这是“当然”。您的问题被简化为从
文件*
生成iostreams
streambuf
。Howard Hinnant回答说,标准没有提供任何方法,但是在
文件*
之上实现一个
streambuf
-派生类非常简单。他甚至提到了一些代码,他认为这是一个很好的起点


请注意,这仅对文本文件有意义。iostreams和二进制文件相处不好;有一个字符编码层,
ios_base::binary
无法关闭该层。

这显然是Windows上Dinkumware中的一个bug。Windows在其大多数API中不支持UTF-8。你应该向Dinkumware的作者提交一份报告。
ifstream
wchar\u t*
版本和
wifstream
版本都应该使用原始值,就像
\wfopen()
一样,而不是转换为UTF-8并调用
fopen()
。这可能适用于其他平台,但不适用于Windows。这是两年前向Embarcadero报告的,它仍然开放。请看。@RemyLebeau纯粹的源代码有一个
#ifdef
设置,可以使所有调用都通过
\u wfopen
进行,但是(据我快速查看所见),它不能使
fstream(char*)
转到
fopen
,并且在同一版本上也有
fstream(wchar\u t*)
转到
\u wfopen
。我不确定C++Builder是否支持让我尝试为
\wfopen
设置重新构建其打包版本的Dinkum?@RemyLebeau谢谢,该报告比购买Josuttis的书(显然远不是理想的tho)有更快的短期解决方法。我在哪里可以阅读更多关于字符编码层的信息?(C++11之前的版本)我突然想到,我可以通过
fread
或类似的方式将整个文件读入内存,然后用原始数据初始化
sstream
,并跨我的fingers@MattMcNabb:绝对值得一试。