2013-11-25 4 views
5

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

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

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

+0

Похоже, вам нужно изменить «кодовую страницу» с UTF-8 на любую кодовую страницу, используемую консолью для китайских иероглифов. Вызовите MultiByteToWideChar, чтобы перейти от UTF-8 к Unicode, а затем WideCharToMultiByte, чтобы перейти от Юникода к локальной кодовой странице. – john

+0

Скорее всего, ошибка консоли. Попробуйте '>' 'войти в файл. Если он окажется действительным UTF-8 с китайскими иероглифами, то ваша программа работает нормально, и это вопрос Windows. (Конечно, вам все равно нужно изменить свою программу для работы с Windows, но вы узнаете, кто виноват.) – aib

+0

@aib Да, когда я перенаправляю std :: string переменную в другой файл, содержимое остается действительным UTF-8 с персонажами Chiese. Кодовая страница моей консоли - «936 (ANSI/OEM - 简体 中文 GBK)». –

ответ

7

Этот код может помочь (он был скомпилирован с VC++ 2010). Я тестировал его с файлом UTF-8, содержащим нелатинские символы, и, похоже, он работает, но я не знаю, будет ли он отлично работать с китайскими иероглифами. Проверьте следующие ссылки для получения дополнительной информации: _setmode и 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 (то есть. Не использовать растровые шрифты).

+1

Было ли ваше решение работать на другой платформе или только VC под Windows? –

1

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

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

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

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

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

  • Нет связанных вопросов^_^