代码之家  ›  专栏  ›  技术社区  ›  neuviemeporte

U+到底代表什么,为什么我不能在我的C++应用程序中创建一个Unicode中间字符串表?

  •  3
  • neuviemeporte  · 技术社区  · 14 年前

    我试图把应用程序从Java+Swing转换成C++ +QT。有一次我不得不处理一些Unicode中间层在Java中,这相当简单:

    private static String[] hiraganaTable = {
        "\u3042", "\u3044", "\u3046", "\u3048", "\u304a", 
        "\u304b", "\u304d", "\u304f", "\u3051", "\u3053", 
        ...
    }
    

    而C++中我有问题:

    QString hiraganaTable[] = {
        "\x30\x42", "\x30\x44", "\x30\x46", "\x30\x48", "\x30\x4a", 
        "\x30\x4b", "\x30\x4d", "\x30\x4f", "\x30\x51", "\x30\x53", 
        ...
    };
    

    我无法在VS2008中使用\u,因为我收到了一堆警告:

    由通用字符名“\u3042”表示的字符不能在当前代码页中表示(1250)

    别叫我蠢,我试着使用文件->高级保存选项,但没有用,代码页似乎根本没有改变。似乎这是一个已知的问题: How to create a UTF-8 string literal in Visual C++ 2008

    我使用的表很短,因此在Vim和一些入门级regexp魔术的帮助下,我能够将它转换为 \x30\x42 符号。不幸的是,qstring无法从这样的输入正确初始化。我什么都试过了。fromAscii(),fromUtf8(),fromLocal8Bit(),QString(QByteArray),作品。然后,尝试将没有BOM的U+3042写入一个文件,然后以hex模式查看它,我发现它实际上是 “E3 81 82号” . 突然,像这样的一个条目似乎起作用了 QString::fromAscii() . 现在我只想知道“U+3042”中的“U+”到底代表多少(因为0xE38182-0x3042=E35140,也许我最好将这个神奇常数添加到所有可能的Unicode字符中?)。我应该如何从这里开始获取正确的UTF-8字符串数组?

    3 回复  |  直到 8 年前
        1
  •  3
  •   MSalters    14 年前

    问题是C++是基于C的,它可以追溯到ASCII时代。“默认”C字符串“abc”是8位。你的VisualC++编译器有16位Unicode(UTF16)文字,但是语法略有不同: L"abc\u3042" . 这种文字的类型是 wchar_t[N] 而不是 char[N] ,您可以将它们存储在 std::wstring .

    Qt完全理解 wchar_t 而qstring可以直接由它们构造而无需转换问题。

        2
  •  4
  •   Ignacio Vazquez-Abrams    14 年前

    你看到的是那个字符的UTF-8编码。

    >>> u'\u3042'.encode('utf-8').encode('hex')
    'e38182'
    

    如果你用UTF-8把它们都写出来,那你就没事了。

    “U+”只是表示您看到的是Unicode码位,而不是某些特定的编码。

    编辑:

    一个小的scriptlet帮助您开始使用Python(与上面的语言相同):

    >>> print ',\n'.join(', '.join('"%s"' % (y.encode('utf-8').encode('string-escape')
          ,) for y in x) for x in [u'あいうえお', u'かきくけこ', u'さしすせそ'])
    "\xe3\x81\x82", "\xe3\x81\x84", "\xe3\x81\x86", "\xe3\x81\x88", "\xe3\x81\x8a",
    "\xe3\x81\x8b", "\xe3\x81\x8d", "\xe3\x81\x8f", "\xe3\x81\x91", "\xe3\x81\x93",
    "\xe3\x81\x95", "\xe3\x81\x97", "\xe3\x81\x99", "\xe3\x81\x9b", "\xe3\x81\x9d"
    
        3
  •  2
  •   Cheers and hth. - Alf    14 年前

    “你+ 尽职调查 “每个 是表示Unicode码位的十六进制数字。

    不能用8位字符存储16位值;这是您遇到的主要问题。

    使用宽字符,例如(这些是字符串文字) L"\0x3042" L"\u3042" .

    然后想办法让QString接受这些。

    注意:VisualC++将发出警告 \U 在文本中使用的表示法,而g++将为在文本之外使用的表示法发出愚蠢的警告。

    干杯。,