2017-03-18 1 views
1

Je programme en C et je veux que tous les UTF (ex: "ru_RU-UTF-8", "en_EN-UTF-8", etc.) passent à la version wchar_t (en utilisant la fonction mbrtowc) . Peu importe ce que wchar_t il convertit à particulièrement, tant que c'est un wchar_t valide dans certains locaux.Existe-t-il un environnement local UTF-8 pour N'IMPORTE QUELLE langue/pays?

Y a-t-il un paramètre "UTF-8-whatever" que je peux transmettre aux paramètres régionaux?

Comme je suis à la recherche de l'exact opposé de setlocale("POSIX")/setlocale("C").

Pour clarifier les choses, le code C ...

setlocale(LC_ALL, "ru_RU.UTF-8"); 
stuff = mbrtowc(.....) 

œuvres, où le code C ...

setlocale(LC_ALL, "en_US.UTF-8"); 
stuff = mbrtowc(.....) 

retours -1 dès qu'elle frappe cyrillique. Les choses que j'ai affaire peuvent aussi avoir des caractères japonais, etc ...

+0

Utilisez une bibliothèque qui gère cela pour vous, comme 'iconv'. Je ne pense pas qu'il existe un tel "* locale *". –

+0

Je vais certainement regarder dans iconv, merci. –

+0

Qu'est-ce que "RU-UTF-8" etc. Et 'wchar_t' n'est pas garanti pour représenter les codages Unicode. Cela dépend de la plate-forme. – Olaf

Répondre

3

Le problème avec les locales et les fonctions de wchar dans C est qu'elles dépendent fortement de la plate-forme. Pour ce que ça vaut, je n'ai aucun problème à convertir l'UTF-8 cyrillique en wchars avec les paramètres régionaux en_US.UTF-8 sous Linux (Ubuntu 16.04). Le code suivant

#include <locale.h> 
#include <stdio.h> 
#include <wchar.h> 

int main() { 
    const char in[] = "\xD0\xB1"; 
    wchar_t out; 
    size_t consumed; 

    setlocale(LC_ALL, "en_US.UTF-8"); 
    consumed = mbrtowc(&out, in, sizeof(in) - 1, NULL); 
    if (consumed > 0) { 
     printf("%04x\n", (unsigned)out); 
    } 

    return 0; 
} 

imprime

0431 

comme prévu. Sur d'autres plateformes, votre kilométrage peut varier. Les plates-formes avec un wchar_t 16 bits comme Windows sont particulièrement problématiques. Mais une plate-forme sensée devrait être capable de coder et de décoder tous les caractères Unicode avec n'importe quel environnement local UTF-8, donc il n'y a pas besoin d'une locale UTF-8 générique.

Si vous souhaitez simplement utiliser UTF-8, vous devez envisager une bibliothèque pour la conversion UTF-8 comme iconv, utf8proc, libunistring ou ICU. Vous pouvez également écrire vos propres routines de conversion. Ce n'est pas trop dur.

+0

' 0431' est _Unicode_ pour 'б'; coller avec le _UTF-8_, à savoir l'hexagone 'D0B1'. –