Как прочитать кириллический файл Unicode в C++?

Я пытаюсь прочитать строки из файлов .txt, которые были сохранены как Unicode. Вот как я это делаю:

wifstream input;
string path = "test.txt";
input.imbue(locale(input.getloc(),
        new codecvt_utf16<wchar_t, 0x10ffff, consume_header>));

input.open(path);
if (input.is_open())
{
    wstring line;
    input.seekg( 1 , ios_base::beg);
    getline(input, line);
}

Он отлично работает для файлов с латинскими символами. Но для кириллических файлов я получаю странные символы вместо пробелов и соседних символов.

Например:

Что во входном файле:

Госдеп США осудил нападение на

Что я получаю:

︓осдепР!ШАР>судилР=ападениеР=а

Что я делаю не так?


person max_hassen    schedule 19.05.2015    source источник
comment
уверен, что это не проблема вывода? то, что вы читаете в юникоде, не означает, что вы выводите в среду юникода.   -  person Marc B    schedule 19.05.2015
comment
Я бы удалил эту строку: input.imbue(locale(input.getloc(), new codecvt_utf16‹wchar_t, 0x10ffff, Consumer_header›));   -  person Leo Chapiro    schedule 19.05.2015
comment
Re Что я делаю неправильно?, Мне очень хочется быть бойким и ответить Использование стандартной библиотеки C++, потому что она должна делать это по умолчанию. Не должно быть необходимости выяснять, как его использовать для этого. Или обойти это.   -  person Cheers and hth. - Alf    schedule 19.05.2015
comment
гхх... Российские политические новости попали в StackOverflow... Нееет...   -  person Mints97    schedule 19.05.2015
comment
о, может открыть файл в бинарном режиме? Попробуй это.   -  person Cheers and hth. - Alf    schedule 19.05.2015
comment
Также обратите внимание, что в Windows 0x10FFFF не подходит для 16-битного wchar_t Windows, указанного как тип Elem. Но должна иметь возможность использовать тип char32_t.   -  person Cheers and hth. - Alf    schedule 19.05.2015
comment
@MarcB, это не проблема вывода, я вижу строку в отладчике.   -  person max_hassen    schedule 19.05.2015
comment
@Cheersandhth.-Альф, попробовал открыть в бинарном режиме, тот же результат.   -  person max_hassen    schedule 19.05.2015
comment
@duDE, если я его удалю, мне нужно как-то преобразовать строку.   -  person max_hassen    schedule 19.05.2015
comment
@ Mints97, так оно и есть ;)   -  person max_hassen    schedule 19.05.2015
comment
Вы уверены, что вводите в UTF16, а не в UTF8?   -  person Petr    schedule 19.05.2015
comment
@Petr, более или менее, с codecvt_utf8 я получаю пустую строку.   -  person max_hassen    schedule 19.05.2015
comment
@malheur, попробуйте просмотреть входной файл в двоичном режиме и убедитесь, что каждое пространство занимает два байта, а не один.   -  person Petr    schedule 19.05.2015


Ответы (2)


одна строка выглядит очень подозрительно в вашем коде:

input.seekg(1, ios_base::beg);

он устанавливает позицию файла, поэтому чтение начальной позиции строки utf16 1 может быть неправильным (неправильно читается спецификация). у меня такой же результат для файла utf16 с прямым порядком байтов.

поэтому вы можете изменить позицию на 0 или удалить эту строку, чтобы этот код работал

person Alexander    schedule 19.05.2015
comment
Я добавил это, потому что в начале файла есть странный символ. Он отлично работал с латинскими файлами. - person max_hassen; 20.05.2015
comment
странный персонаж в начале это BOM я думаю - person Alexander; 20.05.2015

Ну разобрался с образом:

FILE *input= _wfopen(L"test.txt", L"rb");
wchar_t line[1000];
test.txtfgetws(line, 1000, input);

Работает нормально так. Было довольно глупо с моей стороны не попробовать это первым. Так что спасибо всем.

person max_hassen    schedule 20.05.2015