2010-03-17 3 views
2

Возможно ли это? Я пытался прочитать простой файл, содержащий русский, и он явно не работает.Чтение на русском языке (Unicode) с использованием basic_ifstream <wchar_t>

Я назвал file.imbue (loc) (и в этот момент loc правилен, Russian_Russia.1251). И ЬиЕ имеет тип basic_string <wchar_t>

Причина я использую basic_ifstream <wchar_t> происходит потому, что это шаблон (так технически, basic_ifstream <T>, но в этом случае T = wchar_t).

Это все прекрасно работает с английскими символами ...

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

Я не понимаю, почему я получаю мусор при чтении русских символов. (например, если файл содержит хеы хеы хеы, я получаю «яюЕ», 5 (квадрат), K (квадрат) и т. д.

+0

О, прекрасные проблемные потоки в C++ :) Может быть, это может дать вам подсказку: http://stackoverflow.com/questions/1509277/why-does-wide-file-stream-in-c-narrow-written- data-by-default – AraK

+0

Таким образом, действительно нет способа, который позволит использовать шаблонные потоки? Это кажется слишком сложным, как я смотрю на него. Не существует способа, чтобы поток читал определенный тип персонажа вообще? – Mark

+0

Во-первых, «хеы хеы хеы» определенно не русские (хотя в нем есть русские символы). Тогда вы могли бы сделать свой пример «полным» и предоставить ссылку на образец файла (в этом случае я буду рад помочь вам помочь). – mlvljr

ответ

1

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

+0

Итак, std :: basic_ifstream просто не может быть сделано? Тогда почему он существует? Простите характер моих вопросов, я просто вообще не вижу способа читать многобайтовые символы, используя потоки, и пусть они будут чем-то вроде мусора, как только они будут прочитаны, если вы не пишете код специально для каждого типа многобайтовая кодировка, которая полностью поражает точку шаблонов. – Mark

+0

@Mark: Важным моментом здесь является то, что ваш вход не является Unicode. Ожидает ли ваша реализация Unicode? –

+0

Я не совсем уверен, что вы имеете в виду - все, что я знаю, это то, что файл будет либо в ASCII, либо в Unicode (и он должен быть выбран во время компиляции, использовать или не использовать широкие или узкие символы - с использованием шаблона). – Mark

0

Iostreams по умолчанию принимает любые данные на диске в формате, отличном от Юникода, для совместимость с существующими программами, которые не обрабатывают unicode. C++ 0x исправит это, разрешив поддержку родного юникода, но в это время есть std::codecvt<wchar_t, char, mbstate_t>, используемый iostreams для conv ert нормальные данные char в широкие символы для вас. См. Cplusplus.com's description of std::codecvt.

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

+0

Как это используется? Если ты не возражаешь, я спрашиваю. – Mark

+0

Вы просто передаете фасет в basic_istream :: use_facet, как и с любым другим аспектом. –

+0

Я не уверен, что существует ... Может быть, я не понимаю, как работают грани, но я не вижу, как вы могли бы передать один на use_facet, так как я не думаю, что для basic_ifstream определено use_facet. Я мог ошибаться ... – Mark

1

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

0

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

+0

Err .. no, that's языковой стандарт по умолчанию в любом случае. –

Смежные вопросы