现在正好是写blog的时间了,因为那个按照网上的正确代码写成的程序终于开始run了。
先说一下这是如何的一件白痴事情吧:很简单,我不过是要读一个unicode文件,然后把它里面的某几行写到另外一个文件里去罢了。
OK, 看上去是小学生的题目,于是我准备正好练练手,试试看最近学到的standard c++的STL。
wstring, wfstream, wchar_t.......... everything looks correct, except the answer
好了,经过艰苦卓绝的嫌疑排查之后,疑点终于集中在wfstream上了,看上去他每次都只读写byte……(大概荒废了我一个下午)但是他是w-的啊……何况getline里面还有widen('\n')这样的操作。
经过我失败地用C style的东西改写后,work了,看来果然是wfstream的问题,不支持Unicode。
终于……看到变态的解释和解法了:
using namespace std;
typedef codecvt Mybase;
// CLASS Simple_codecvt
class Simple_codecvt : public Mybase
{
public:
typedef wchar_t _E;
typedef char _To;
typedef mbstate_t _St;
explicit Simple_codecvt(size_t _R = 0)
: Mybase(_R) {}
protected:
virtual result do_in(_St& _State, const _To *_F1, const _To *_L1, const _To *&_Mid1, _E *F2, _E *_L2, _E *&_Mid2) const
{return (noconv);}
virtual result do_out(_St& _State, const _E *_F1, const _E *_L1, const _E *&_Mid1, _To *F2, _E *_L2, _To *&_Mid2) const
{return (noconv);}
virtual result do_unshift(_St& _State, _To *_F2, _To *_L2, _To *&_Mid2) const
{return (noconv);}
virtual int do_length(_St& _State, const _To *_F1, const _To *_L1, size_t _N2) const _THROW0()
{return (_N2 < (size_t)(_L1 - _F1)? _N2 : _L1 - _F1); } virtual bool do_always_noconv() const _THROW0()
{return (true);}
virtual int do_max_length() const _THROW0()
{return (2);}
virtual int do_encoding() const _THROW0()
{return (2);}
};
#include
int _tmain(int argc, TCHAR* argv[])
{
const char *fname = "filename.txt"; // or whatever locale loc = _ADDFAC(locale::classic(), new Simple_codecvt);
wofstream myostr;
myostr.imbue(loc);
myostr.open(fname, ios_base::binary);
if (!myostr.is_open())
cerr << "can't write to " << fname << endl;
return 0;
}
算了,我承认我高估STL了,或者说是VC上的STL
不讲了,累死了,有兴趣自己看
http://www.codeproject.com/vcpp/stl/upgradingstlappstounicode.asp?df=100&forumid=16224&exp=0&select=646006