【问题标题】:Print wchar to Linux console?将 wchar 打印到 Linux 控制台?
【发布时间】:2011-12-03 11:32:07
【问题描述】:

我的 C 程序粘贴在下面。在bash中,程序打印“char is”,Ω 不打印。我的语言环境都是 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);
}

【问题讨论】:

    标签: c linux console wchar-t wchar


    【解决方案1】:

    使用 {glib,libiconv,ICU} 将其转换为 UTF-8 后再输出。

    【讨论】:

    • 谢谢。我可以不使用这些库吗?
    【解决方案2】:

    这很有趣。显然编译器将欧米茄从 UTF-8 转换为 UNICODE,但不知何故 libc 把它搞砸了。

    首先:%c-format 说明符需要 char(即使在 wprintf-版本中),因此您必须指定 %lc(因此对于字符串指定 %ls)。

    其次,如果您像这样运行代码,则语言环境设置为C(它不会自动从环境中获取)。您必须使用空字符串调用 setlocale 才能从环境中获取语言环境,因此 libc 再次感到高兴。

    #include <stdio.h>
    #include <wchar.h>
    #include <stdlib.h>
    #include <locale.h>
    
    int main() {
        int r;
        wchar_t myChar1 = L'Ω';
        setlocale(LC_CTYPE, "");
        r = wprintf(L"char is %lc (%x)\n", myChar1, myChar1);
    }
    

    【讨论】:

    • 其实这是意料之中的。 libc 不会乱来,它只是遵循标准。
    • 谢谢,但你能提供一些细节吗?你是什​​么意思语言环境设置为“C”?
    【解决方案3】:

    除了建议修复 LIBC 的答案,您可以这样做:

    #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;
    }
    

    【讨论】:

    • 这个答案很傻;开始使用wchar_t 的唯一一点是,理论上您可以在不同的语言环境中支持不同的输出编码。如果你想硬编码 UTF-8,只需使用char *myChar1 = "Ω";,然后使用printf%s...
    • 我将我的答案视为一种解决方法,或者在一些更有限的用例中可能是一种解决方案。我喜欢被选为解决方案的答案,所以这里没有争论。干杯。
    猜你喜欢
    • 2013-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-22
    • 2016-09-21
    相关资源
    最近更新 更多