Как прочитать файл в кодировке UTF-8, содержащий китайские символы, и правильно вывести их на консоль?

Я пишу сканер для поиска некоторых китайских веб-файлов. Извлеченные файлы кодируются в utf-8. И мне нужно прочитать этот файл, чтобы разобраться, например, извлечь URL и китайские иероглифы. Но я обнаружил, что когда я читал файл в переменную std :: string и выводил его в консоль, китайские символы становились символами мусора. Я применил boost :: regex к переменной std :: string и могу извлечь все URL, кроме китайских символов.

Как я могу решить эти проблемы?

Постскриптум Мои файлы CPP по умолчанию закодированы как ANSI, операционная система Win8 на китайском языке;

5

Решение

Этот код может помочь (он был скомпилирован с VC ++ 2010). Я протестировал его с файлом UTF-8, содержащим нелатинские символы, и он, кажется, работает, но я не знаю, будет ли он работать нормально с китайскими символами. Проверьте следующие ссылки для получения дополнительной информации: _установить режим а также codecvt_utf8.

#include <iostream>
#include <fstream>
#include <string>
#include <locale>
#include <codecvt>
#include <fcntl.h>
#include <io.h>

using namespace std;    // Sorry for this!

void read_all_lines(const wchar_t *filename)
{
wifstream wifs;
wstring txtline;
int c = 0;

wifs.open(filename);
if(!wifs.is_open())
{
wcerr << L"Unable to open file" << endl;
return;
}
// We are going to read an UTF-8 file
wifs.imbue(locale(wifs.getloc(), new codecvt_utf8<wchar_t, 0x10ffff, consume_header>()));
while(getline(wifs, txtline))
wcout << ++c << L'\t' << txtline << L'\n';
wcout << endl;
}

int _tmain(int argc, _TCHAR* argv[])
{
// Console output will be UTF-16 characters
_setmode(_fileno(stdout), _O_U16TEXT);
if(argc < 2)
{
wcerr << L"Filename expected!" << endl;
return 1;
}
read_all_lines(argv[1]);
return 0;
}

Если китайские символы выглядят не так, как ожидалось, убедитесь, что консоль использует шрифт, который поддерживает UTF-16 (т.е. не используйте растровые шрифты).

7

Другие решения

В общем, используйте w варианты, (wstring, wfstream, wcout), установите ваши локали в соответствии с требованиями, повесьте L на передней части строковых литералов. locale::global(locale("")) устанавливается так, чтобы соответствовать среде по умолчанию, а затем в каждом потоке, который не работает в соответствии с этим значением по умолчанию, например wcout.imbue(locale("Chinese_China.936")) может быть имя Microsoft для региональных настроек вашего терминала. Этого всегда было достаточно, чтобы делать то, что я хочу, надеюсь, это сработает и для вас.

#include <iostream>
#include <locale>
using namespace std;
int main() {
locale::global(locale(""));
wstring word;
while (wcin >>word)
wcout<<word<<'\n';
wcout<<L"好運n";
}
1

если вам нужно правильно отображать символы, вы можете использовать libiconv из GNU.
если вам нужно только обработать URL, std :: string работает нормально.
проблема в кодовой странице консоли Windows, а не в самой строке.
Использование locale зависит от реализации os и stdc ++ lib, поэтому я не рекомендую использовать.

MultiByteToWideChar окна может помочь, но вам нужно проверить спецификации MS о том, как эти функции выполняют преобразования в строках.

0