我希望即时转码字符编码。我想使用iostream和我自己的转码streambuf
,例如:
xcoder_streambuf xbuf( "UTF-8", "ISO-8859-1", cout.rdbuf() );
cout.rdbuf( &xbuf );
char *utf8_s; // pointer to buffer containing UTF-8 encoded characters
// ...
cout << utf8_s; // characters are written in ISO-8859-1
xcoder_streambuf
的实施将使用ICU的转换器API。这将使数据进入(在这种情况下,来自utf8_s
),对其进行转码,并使用iostream的原始steambuf
将其写出来。
这是一种合理的方式吗?如果不是,那会更好一点?
答案 0 :(得分:0)
这是一种合理的方式吗?
是的,但这不是你在现代(如1997年)iostream中所期望的那样。
通过basic_streambuf<>
输出的行为由overflow(int_type c)
虚函数定义。
basic_filebuf<>::overflow(int_type c = traits::eof())
的说明包括a_codecvt.out(state, b, p, end, xbuf, xbuf+XSIZE, xbuf_end);
,其中a_codecvt
定义为:
const codecvt<charT,char,typename traits::state_type>& a_codecvt
= use_facet<codecvt<charT,char,typename traits::state_type> >(getloc());
所以您需要使用相应的imbue
转换器locale
codecvt<charT,char,typename traits::state_type>
。
类
codecvt<internT,externT,stateT>
用于从一种字符编码转换为另一种字符编码时,例如从宽字符到多字节字符或在宽字符编码(如Unicode和EUC)之间。
自1997年以来,对Unicode的标准库支持取得了一些进展:
专门化codecvt在UTF-32和UTF-8编码方案之间进行转换。
这似乎是你想要的(ISO-8859-1代码是USC-4代码= UTF-32)。
如果没有,会有什么更好的?
我会为UTF8引入一种不同的类型,例如:
struct utf8 { unsigned char d; // d for data }; struct latin1 { unsigned char c; // c for character };
这样你就不会意外地传递需要ISO-8859- *的UTF8。但是,您必须编写一些接口代码,并且您的流类型不会是istream
/ ostream
。
免责声明:我从未真正做过这样的事情,所以我不知道它在实践中是否可行。