Обработка UTF-8 в С++

Чтобы узнать, является ли С++ правильным языком для моего проекта, я хочу проверить возможности UTF-8. Согласно ссылкам, я построил этот пример:

#include <string>
#include <iostream>

using namespace std;

int main() {
    wstring str;
    while(getline(wcin, str)) {
        wcout << str << endl;
        if(str.empty()) break;
    }

    return 0;
}

Но когда я печатаю символ UTF-8, это неправильно:

$ > ./utf8 
Hello
Hello
für
f
$ >

Не только он не печатает ü, но и немедленно завершает работу. gdb сказал мне, что не было крушения, но нормальный выход, но я считаю, что трудно поверить.

Ответ 1

Не используйте wstring для Linux.

std:: wstring VS std::string

Взгляните на первый ответ. Я уверен, что он отвечает на ваш вопрос.

  • Когда я должен использовать std:: wstring над std::string?

В Linux? Больше никогда (§).

В Windows? Почти всегда (§).

Ответ 2

Сам язык не имеет ничего общего с юникодом или любым другим кодированием символов. Он привязан к операционной системе. Windows использует UTF16 для поддержки Unicode, что подразумевает использование широких символов (16-разрядных символов) - wchar_t или std: wstring. Каждая функция Win Api, работающая со строками, требует широкого ввода char.

Но системы на основе unix, то есть Mac OS X или Linux используют UTF8. Конечно - дело только в том, как вы обрабатываете байты в массиве, поэтому вы можете иметь строку UTF16, хранящуюся в общем массиве C или std: string. Вот почему вы не видите никаких wstrings в кросс-платформенном коде; вместо этого все строки обрабатываются как UTF8 и перекодируются, когда необходимо, в UTF16 (на окнах).

У вас есть больше возможностей, как справиться с этим немного запутанным. Я лично делаю это, как упоминалось выше, строго используя кодировку UTF8 во всем приложении, перекодируя строки при взаимодействии с Windows Api и непосредственно используя их в Mac OS X. Для перекодирования выигрыша я использую большие помощники преобразования:

С++ UTF-8 Помощники по конверсиям (в MSDN, доступном под лицензией Apache, версия 2.0).

Вы также можете использовать кросс-платформенную Qt String, которая определяет функции преобразования из UTF8 в/из UTF16 и другие кодировки (ANSI, Latin...).

Итак, ответ выше - при использовании unix всегда UTF8 (std::string, char), в Windows UTF16 (std:: wstring, wchar_t) истинно.

Ответ 3

Помните, что при запуске основной программы по умолчанию выбран локаль "C". Вероятно, вы не хотите этого, если будете обрабатывать utf-8. Вызов setlocale(LC_CTYPE, "") отключает это значение по умолчанию, и вы получаете все, что определено в среде (предположительно, язык utf-8).