8
votes

Imprimer la console WCHAR à Linux?

Mon programme C est collé ci-dessous. À bash, le programme Imprimer "Char est", Î © © n'est pas imprimé. Mes paramètres régionaux sont tous EN_US.UTF8.

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

int main() {
   int r;
   wchar_t myChar1 = L'Ω';
   r = wprintf(L"char is %c\n", myChar1);
}


0 commentaires

3 Réponses :


4
votes

Utilisez {GLIB, LIBICONV, ICU} pour le convertir en UTF-8 avant de sortir.


1 commentaires

Merci. Puis-je le faire en n'utilisant pas ces libs?



14
votes

C'était assez intéressant. Apparemment, le compilateur traduit l'oméga de UTF-8 à UNICODE, mais la LIBC est en quelque sorte mortes.

Tout d'abord: le spécificateur % c -Format attend un char (Même dans le WPRINTF -Version), vous devez donc spécifier % lc < / code> (et donc % ls pour chaînes).

Deuxièmement, si vous exécutez votre code comme celui-ci, le paramètre local est défini sur c (il n'est pas automatiquement tiré de l'environnement). Vous devez appeler SetLocale avec un vide String pour prendre les paramètres régionaux de l'environnement, le libc est donc heureux à nouveau. xxx


2 commentaires

En fait, c'est comme prévu. Libc ne gâche pas, cela suit simplement la norme.


Merci, mais pouvez-vous donner quelques détails? Que voulez-vous dire que les paramètres régionaux sont définis sur 'c'?



6
votes

Alternativement à la réponse suggérant la fixation de libc, vous pouvez le faire:

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

// NOTE: *NOT* thread safe, not re-entrant
const char* unicode_to_utf8(wchar_t c)
{
    static unsigned char b_static[5];
    unsigned char* b = b_static; 

    if (c<(1<<7))// 7 bit Unicode encoded as plain ascii
    {
        *b++ = (unsigned char)(c);
    }
    else if (c<(1<<11))// 11 bit Unicode encoded in 2 UTF-8 bytes
    {
        *b++ = (unsigned char)((c>>6)|0xC0);
        *b++ = (unsigned char)((c&0x3F)|0x80);
    }
    else if (c<(1<<16))// 16 bit Unicode encoded in 3 UTF-8 bytes
        {
        *b++ = (unsigned char)(((c>>12))|0xE0);
        *b++ =  (unsigned char)(((c>>6)&0x3F)|0x80);
        *b++ =  (unsigned char)((c&0x3F)|0x80);
    }

    else if (c<(1<<21))// 21 bit Unicode encoded in 4 UTF-8 bytes
    {
        *b++ = (unsigned char)(((c>>18))|0xF0);
        *b++ = (unsigned char)(((c>>12)&0x3F)|0x80);
        *b++ = (unsigned char)(((c>>6)&0x3F)|0x80);
        *b++ = (unsigned char)((c&0x3F)|0x80);
    }
    *b = '\0';
    return b_static;
}


int main() {
    int r;
    wchar_t myChar1 = L'Ω';
    r = printf("char is %s\n", unicode_to_utf8(myChar1));
    return 0;
}


2 commentaires

Cette réponse est stupide; Le seul point d'utilisation wchar_t pour commencer est que vous pouvez prendre en charge théoriquement des codages de sortie différents dans différents groupes locaux. Si vous souhaitez que le code dur UTF-8, utilisez simplement char * mychar1 = "Ω"; , puis printf avec % s .. .


Je traite ma réponse comme une solution de contournement ou éventuellement une solution dans des cas d'utilisation plus limitée. J'aime la réponse qui a été choisie comme une solution alors aucun argument ici. À votre santé.