【问题标题】:Printing to the terminal in a encoding neutral manner以编码中性方式打印到终端
【发布时间】:2012-01-09 20:45:56
【问题描述】:

无论其编码如何(UTF-8、16、32),我都想在屏幕上打印一个字符串。该字符串以 char 数组表示,因此我需要忽略空字节并继续打印到标准输出;这让 printf 的家人和朋友无话可说。

char text[] = { 0x00, 0x55, 0x00, 0x6E, 0x00, 0x69, 0x00, 0x63, 0x00, 0x6F, 0x00, 0x64, 0x00, 0x65 };

fwrite( text, sizeof(char), sizeof(text), stdout );

为此,我选择了上述解决方案,以使我能够打印所有 UTF 编码格式。我知道某些终端无法正确显示字符,但这不是我关心的问题,因为它是应用程序之外的可配置选项。

我的应用程序设置了要加载的消息目录(en_EN.UTF-8 等),但我想避免必须根据当前选择的语言环境在代码中进行字符串转换。

在我让它上线之前,能否请我对这种方法进行审查?

【问题讨论】:

    标签: c locale fwrite utf


    【解决方案1】:

    你不能那样做。当您处理文本时,编码很重要。所以你必须进行转换。

    而且将内容保存在 char 数组中也很糟糕,您应该使用 byte 数组。因为:

    • 如果尚未在某些标头中定义,则应将字节定义(或 typedef)为无符号字符。普通字符可以有符号也可以无符号,你会有惊喜。
    • 更具可读性,因为它使意图更加清晰。我看到字节,它是一堆字节。我看到 char,它是纯文本(在你的情况下,显然不是这样)

    【讨论】:

    • 我不确定我是否完全理解你。关于字节数组的可读性,我明白了这一点。但是您的评论是我需要转换字符串。如果终端采用 utf16 编码字符并且我编写了一个表示 utf16 的字节数组,则它仍应正确显示。如果我随后将终端更改为 utf8 编码并加载 utf8 字符串,这应该再次显示。没有?
    • @Ben 如果终端在大端模式下接受 utf16 并且您传递以小端模式编码的字节数组,那么答案是否定的,这将不会在终端上正确显示。
    • 好的,谢谢你的时间。这是根据语言环境进行选择的要点
    • @Ben:如果终端使用 UTF-16 并且您的数组包含 UTF-16 的字节,那么您可能没问题。但我的理解是,您想对任何终端设置使用相同的数组。但是,即使您对 UTF-16LE 终端使用“UTF-16LE 字节”,对 UTf-8 终端使用“UTF-8 字节”等等,仍然不能保证像 fwrite 这样的函数会通过相同的“管道”作为“终端感知”的普通 printf,因此即使“字节正确”,您可能仍然会遇到复杂脚本的问题(例如)。
    【解决方案2】:

    如果您在 Big-Endian 模式下定义 char 数组并且终端接受 Little-Endian 怎么办?还是vice-versa? 我也认为,在处理 char -> Utf 事物时,你不能没有转换(仅因为字节序)。定义一些也是合理的

    typedef unsigned char  utf8char;
    typedef unsigned short utf16char;
    typedef unsigned int   utf32char;
    

    typedef enum {
       BIG_ENDIAN,
       LITTLE_ENDIAN
    } CHAR_ENDIANNESS
    

    这样,您将更透明地转换为 UTF,调试会更容易,代码维护也会得到改善。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-14
      • 1970-01-01
      • 1970-01-01
      • 2013-04-29
      • 2012-12-19
      • 1970-01-01
      • 2013-06-27
      • 2013-09-14
      相关资源
      最近更新 更多