Обработка UTF-8 в C ++ - PullRequest
       64

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

11 голосов
/ 15 декабря 2011

Чтобы выяснить, является ли C ++ подходящим языком для моего проекта, я хочу проверить возможности 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 сказал мне, что не было сбоев, но был нормальный выход, но мне трудно в это поверить.

Ответы [ 3 ]

9 голосов
/ 15 декабря 2011

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

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

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

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

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

Таким образом, ответ выше - в Unix всегда используйте UTF8 (std :: string, char), в Windows UTF16 (std :: wstring, wchar_t) - true.

8 голосов
/ 15 декабря 2011

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

std :: wstring VS std :: string

Посмотрите на первый ответ. Я уверен, что это отвечает на ваш вопрос.

  1. Когда мне следует использовать std :: wstring вместо std :: string?

В Linux? Почти никогда (§).

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

4 голосов
/ 26 февраля 2012

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

...