EN

pcosmos.ca

l'univers de Philippe Choquette

Accueil
Nouvelles
Profil
Contact
Half-Life
Musique
PCASTL
Informatique
Vidéos
Lecture
OpenGL
Éléments
sids du C64
Liens
Exemple ICU
Boyer-Moore
Tri fusion
Ordinateurs

Exemple d'utilisation de ICU en C++ sur MacOS

Lorsque je copie des fichiers de mon Mac vers mon NAS, leurs noms qui ont des caractères accentuées composés sont automatiquement décomposés pour les copies. Ceci cause à mon outil de backup de prendre les copies pour des fichiers sans originaux. Voir Unicode Normalization Forms pour des exemples de caractères composés. Comme solution, j'ai écrit un programme qui renomme tous les fichiers originaux à la forme décomposée. Ainsi, la décomposition automatique ne change rien. Voici les premières étapes qui ont mené à cette solution.

Installation de icu4c dans Brew :

brew install icu4c

Installation de pkgconf dans Brew :

brew install pkgconf

Affichage de /opt dans Finder :

sudo chflags nohidden /opt

Assignation de la bonne valeur à la variable PKG_CONFIG_PATH :

PKG_CONFIG_PATH=/opt/homebrew/Cellar/icu4c@77/77.1/lib/pkgconfig
export PKG_CONFIG_PATH

Exemple de transliterate :

#include <iostream>
#include <string>
#include <unicode/unistr.h>
#include <unicode/translit.h>

int main(void)
{
    std::string init("t\xC3\xA4st"); // täst

    icu::UnicodeString ustrc = icu::UnicodeString::fromUTF8(init.c_str());

    const char16_t *ustrc_buf = ustrc.getBuffer();
    for (int i = 0; i < ustrc.length(); i++)
    {
        std::cout << std::hex << ustrc_buf[i] << " ";
    }
    std::cout << std::endl;

    UErrorCode status = U_ZERO_ERROR;
    icu::Transliterator *myTrans = icu::Transliterator::createInstance("Any-NFD",
        UTRANS_FORWARD, status);

    myTrans->transliterate(ustrc);
    for (int i = 0; i < ustrc.length(); i++)
    {
        std::cout << std::hex << ustrc_buf[i] << " ";
    }
    std::cout << std::endl;

    std::string result;
    icu::StringByteSink<std::string> bs(&result);
    ustrc.toUTF8(bs);

    return 0;
}

Explication :
0xC3 0xA4 est l'encodage UTF-8 de ä composé.
Voir Unicode Character ä
Any-NFD est une règle de translitération prédéfinie de tous vers Normalization Form D (NFD) (la décomposition canonique).

Pour compiler :

c++ -o exemple exemple.cpp -std=c++17 `pkg-config --libs --cflags icu-uc icu-i18n`

Le paramètre icu-uc est nécessaire pour les types de données et le paramètre icu-i18n est nécessaire pour linker avec createInstance et transliterate.
Référence : How To Use ICU

Le programme affiche :

74 e4 73 74
74 61 308 73 74

Car 0x00E4 est l'encodage UTF-16 de ä composé.
U+0061 avec U+0308 est la décomposition de ä (0x0061 est "a" et 0x0308 est le tréma uniquement). result commencera par 0x74 0x61 0xCC 0x88 car l'encodage UTF-8 du tréma est 0xCC 0x88.

Mobile
linkedin
bandcamp
steam