Чтение русских символов (Unicode) с использованием basic_ifstream <wchar_t> - PullRequest
2 голосов
/ 17 марта 2010

Возможно ли это вообще? Я пытался прочитать простой файл, который содержит русский язык, и он явно не работает.

Я вызвал file.imbue (loc) (и на данный момент loc - это правильно, Russian_Russia.1251). И buf имеет тип basic_string

Причина, по которой я использую basic_ifstream , заключается в том, что это шаблон (так технически, basic_ifstream , но в данном случае 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 ]

1 голос
/ 17 марта 2010

Все еще есть много реализаций STL, в которых нет std :: codecvt, способных обрабатывать кодировки Unicode. Их шаблонные потоки wchar_t по умолчанию будут использовать системную кодовую страницу, даже если в противном случае они поддерживают Unicode, например, для имени файла. Если файл на самом деле содержит UTF-8, они будут создавать ненужные файлы. Может быть это поможет .

1 голос
/ 17 марта 2010

Кодовая страница 1251 не для Unicode - если память служит, это для 8859-5. К сожалению, есть вероятность, что ваша реализация iostream не поддерживает UTF-16 "из коробки". Это немного странно, поскольку для этого потребуется просто передать данные без изменений, но большинство все еще не поддерживают их. Для чего это стоит, по крайней мере, если я правильно помню, C ++ 0x должен добавить это.

0 голосов
/ 17 марта 2010

Я не уверен, но вы можете попробовать вызвать setlocale (LC_CTYPE, "");

0 голосов
/ 17 марта 2010

Iostreams по умолчанию предполагает, что любые данные на диске не в формате Unicode, для совместимости с существующими программами, которые не обрабатывают Unicode. C ++ 0x исправит это, разрешив встроенную поддержку юникода, но в настоящее время iostreams использует std::codecvt<wchar_t, char, mbstate_t> для преобразования обычных данных char в широкие символы. См. описание cplusplus.com std :: codecvt .

Если вы хотите использовать юникод с iostreams, вам нужно указать фасет codecvt с формой std::codecvt<wchar_t, wchar_t, mbstate_t>, который просто передает данные без изменений.

...