使用basic_ifstream <wchar_t> </wchar_t>读取俄语字符(Unicode)

时间:2010-03-17 16:57:08

标签: c++ locale ifstream

这甚至可能吗?我一直在尝试阅读一个包含俄语的简单文件,但它显然无效。

我已经调用了file.imbue(loc)(此时,loc是正确的,Russian_Russia.1251)。 buf的类型为basic_string&lt; wchar_t&gt;

我使用basic_ifstream&lt; wchar_t&gt;的原因是因为这是一个模板(所以从技术上讲,basic_ifstream&lt; T&gt;,但在这种情况下,T = wchar_t)。

这一切都与英文字符完美搭配......

while (file >> ch)
{
    if(isalnum(ch, loc))
    {
        buf += ch;
    }
    else if(!buf.empty())
    {
        // Do stuff with buf.
        buf.clear();
    }
}

我不明白为什么我在读俄语字符时会弄脏垃圾。 (例如,如果文件包含хеыхеыхеы,我会得到“яюE”,5(方形),K(方形)等...

4 个答案:

答案 0 :(得分:1)

代码页1251不适用于Unicode - 如果内存服务,则为8859-5。不幸的是,你的iostream实现可能不支持UTF-16“开箱即用”。这有点奇怪,因为这样做只会涉及通过未更改传递数据,但大多数仍然不支持它。至于它的价值,至少如果我没记错的话,C ++ 0x应该添加它。

答案 1 :(得分:1)

仍有许多STL实现没有可以处理Unicode编码的std :: codecvt。他们的wchar_t模板化流将默认为系统代码页,即使它们是否为文件名启用了Unicode。如果文件实际上包含UTF-8,它们将产生垃圾。也许是this will help

答案 2 :(得分:0)

默认情况下,Iostream假定磁盘上的任何数据都采用非unicode格式,以便与不处理unicode的现有程序兼容。 C ++ 0x将通过允许本机unicode支持来解决这个问题,但此时iostreams使用std::codecvt<wchar_t, char, mbstate_t>将普通的char数据转换为宽字符。请参阅cplusplus.com的description of std::codecvt

如果你想使用带有iostream的unicode,你需要指定一个形式为std::codecvt<wchar_t, wchar_t, mbstate_t>的codecvt facet,它只是不改变数据。

答案 3 :(得分:0)

我不确定,但您可以尝试调用setlocale(LC_CTYPE,“”);