Ara*_*raK 18 c++ unicode file wofstream
老实说,我只是没有在C++标准库中得到以下设计决定.将宽字符写入文件时,将wofstream
转换wchar_t
为char
字符:
#include <fstream>
#include <string>
int main()
{
using namespace std;
wstring someString = L"Hello StackOverflow!";
wofstream file(L"Test.txt");
file << someString; // the output file will consist of ASCII characters!
}
Run Code Online (Sandbox Code Playgroud)
我知道这与标准有关codecvt
.还有codecvt
的utf8
在Boost
.此外,还有一个codecvt
用于utf16
由马丁·约克在这里SO.现在的问题是,为什么在standard codecvt
转换宽字符?为什么不按原样写人物!
另外,我们是否会unicode streams
使用C++ 0x或者我在这里遗漏了什么?
Éri*_*ant 13
对于第一个问题非常局部答案:文件是字节左右的序列,其中当处理wchar_t
的,至少一些之间的转换wchar_t
和char
必须发生."智能地"进行这种转换需要知道字符编码,因此这就是为什么允许这种转换依赖于语言环境,因为在流的语言环境中使用了一个方面.
然后,问题是如何在标准所要求的唯一区域设置中进行转换:"经典"转换.对此没有"正确"的答案,因此标准对此非常模糊.我从你的问题中了解到,你认为在wchar_t []和char []之间盲目地(或memcpy() - )会是一个好方法.这不是不合理的,事实上在某些实现中是(或至少是)完成的.
另一个POV是,因为codecvt是一个locale facet,所以有理由期望使用"locale的编码"进行转换(我在这里手写,因为概念非常模糊).例如,可以预期土耳其语语言环境使用ISO-8859-9或日语使用Shift JIS.通过相似性,"经典"语言环境将转换为此"语言环境的编码".显然,微软选择简单修剪(如果我们假设wchar_t
代表UTF-16并且我们保持在基本的多语言平面中,则导致IS-8859-1 ),而我知道的Linux实现决定坚持使用ASCII.
对于你的第二个问题:
另外,我们是否会使用C++ 0x获得真正的unicode流,或者我在这里遗漏了什么?
在n2857的[locale.codecvt]部分(我手头的最新C++ 0x草案)中,可以读到:
专业化
codecvt<char16_t, char, mbstate_t>
在UTF-16和UTF-8编码方案codecvt <char32_t, char, mbstate_t>
之间进行转换,专业化在UTF-32和UTF-8编码方案之间进行转换.codecvt<wchar_t,char,mbstate_t>
在本地字符集之间转换窄字符和宽字符.
在[locale.stdcvt]部分中,我们发现:
对于方面
codecvt_utf8
: - 方面应在程序内转换UTF-8多字节序列和UCS2或UCS4(取决于Elem的大小).[...]对于方面
codecvt_utf16
: - 方面应在程序内转换UTF-16多字节序列和UCS2或UCS4(取决于Elem的大小).[...]对于方面
codecvt_utf8_utf16
: - 方面应在程序内转换UTF-8多字节序列和UTF-16(一个或两个16位代码).
所以我猜这意味着"是",但你必须更准确地确定"真正的unicode流"的含义.
C++用于charsets的模型继承自C,因此可以追溯到至少1989年.
两个要点:
因此,要获得任何内容,您必须设置区域设置.
如果我使用简单的程序
#include <locale>
#include <fstream>
#include <ostream>
#include <iostream>
int main()
{
wchar_t c = 0x00FF;
std::locale::global(std::locale(""));
std::wofstream os("test.dat");
os << c << std::endl;
if (!os) {
std::cout << "Output failed\n";
}
}
Run Code Online (Sandbox Code Playgroud)
它使用环境语言环境并将代码0x00FF的宽字符输出到文件.如果我要求使用"C"语言环境,我会得到
$ env LC_ALL=C ./a.out
Output failed
Run Code Online (Sandbox Code Playgroud)
语言环境无法处理宽字符,并且在IO失败时我们会收到问题通知.如果我运行问一个UTF-8语言环境,我明白了
$ env LC_ALL=en_US.utf8 ./a.out
$ od -t x1 test.dat
0000000 c3 bf 0a
0000003
Run Code Online (Sandbox Code Playgroud)
(od -t x1只是转储以十六进制表示的文件),正是我对UTF-8编码文件的期望.
归档时间: |
|
查看次数: |
7938 次 |
最近记录: |