【问题标题】:c++: getting ascii value of a wide charc ++:获取宽字符的ascii值
【发布时间】:2023-04-04 14:25:01
【问题描述】:

假设我有一个像“äa”这样的字符数组。 有没有办法获取第一个字符的 ascii 值(例如 228),它是一个多字节? 即使我将数组转换为 wchar_t * 数组,我也无法获得“ä”的 ascii 值,因为它有 2 个字节长。 有没有办法做到这一点,我现在尝试了 2 天:(

我正在使用 gcc。

谢谢!

【问题讨论】:

    标签: c++ c ascii multibyte


    【解决方案1】:

    你自相矛盾。像 ä 这样的国际字符(根据定义)不是 in ASCII 字符集,因此它们没有“ascii 值”。

    这取决于你的两个字符数组的确切编码,你是否可以获得单个字符的代码点,如果可以,它将采用哪种格式。

    【讨论】:

    • ascii 范围内字符的 unicode 代码与 ascii 编码相同。因此,在 wchar 的情况下,您可以采用最低有效字节并具有 ascii 代码。实际上作者的意思并非如此,我在回答中解释了
    【解决方案2】:

    你很困惑。 ASCII 只有小于 128 的值。值 228 对应于 8 位字符集 ISO-8859-1、CP1252 和其他一些字符集中的 ä。它也是 Unicode 系统中 ä 的 UCS 值。如果您使用字符串文字“ä”并获得一个包含两个字符的字符串,则该字符串实际上是用 UTF-8 编码的,您可能希望解析 UTF-8 编码以获取 Unicode UCS 值。

    您真正想做的更有可能是从一种字符集转换为另一种字符集。如何执行此操作在很大程度上取决于您的操作系统,因此需要更多信息。您还需要指定您到底想要什么?可能是 ISO-8859-1 的 std::string 或 char*?

    【讨论】:

      【解决方案3】:

      有一个标准 C++ 模板函数可以进行这种转换,ctype::narrow()。它是localization library 的一部分。如果可能,它会将宽字符转换为您当前本地的等效字符值。正如其他答案所指出的那样,并不总是存在映射,这就是为什么 ctype::narrow() 采用默认字符,如果没有映射,它将返回。

      【讨论】:

        【解决方案4】:

        取决于您的 char 数组中使用的编码。

        如果您的 char 数组是拉丁 1 编码的,那么它的长度为 2 个字节(加上可能是 NUL 终止符,我们不在乎),这 2 个字节是:

        • 0xE4(小写变音符号)
        • 0x61(小写a)。

        请注意,Latin 1 不是 ASCII,0xE4 也不是 ASCII 值,它是 Latin 1(或 Unicode)值。

        你会得到这样的值:

        int i = (unsigned char) my_array[0];
        

        如果您的 char 数组是 UTF-8 编码的,那么它是三个字节长,这些字节是:

        • 二进制 11000011(UTF-8 编码 0xE4 的第一个字节)
        • 二进制 10100100(UTF-8 编码 0xE4 的第二个字节)
        • 0x61(小写a)

        要恢复使用 UTF-8 编码的字符的 Unicode 值,您要么需要根据 http://en.wikipedia.org/wiki/UTF-8#Description 自己实现它(在生产代码中通常是个坏主意),要么您需要使用特定于平台的 unicode -to-wchar_t 转换例程。在 linux 上这是 mbstowcsiconv,尽管对于单个字符,您可以使用 mbtowc,前提是为当前语言环境定义的多字节编码实际上是 UTF-8:

        wchar_t i;
        if (mbtowc(&i, my_array, 3) == -1) {
            // handle error
        }
        

        如果是 SHIFT-JIS 那么这不起作用...

        【讨论】:

          【解决方案5】:

          您想要的称为音译 - 将一种语言的字母转换为另一种语言。它与 unicode 和 wchars 无关。你需要一个映射表。

          【讨论】:

            猜你喜欢
            • 2017-09-08
            • 2010-09-28
            • 2013-11-20
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多