代码之家  ›  专栏  ›  技术社区  ›  Szymon Lipiński

我的程序如何从ASCII码切换到Unicode码?

  •  7
  • Szymon Lipiński  · 技术社区  · 15 年前

    我想写一个C++程序,应该在UNIX和Windows上工作。这个程序应该能够同时使用Unicode和非Unicode环境。其行为应仅取决于环境设置。

    我想拥有的一个很好的特性是操纵从目录中读取的文件名。这些可以是unicode。。。不管怎样。

    6 回复  |  直到 15 年前
        1
  •  9
  •   Community CDub    8 年前

    我想用C++编写一个程序 应该在Unix和Windows上工作。

    在Unicode之前的日子里,这两种平台都很相似,因为每种语言环境都有自己喜欢的字符编码。字符串是 char 烧焦 =一个字符,除了在少数东亚地区使用双字节编码(由于非自同步而难以处理)。

    但他们以两种不同的方式接近Unicode。

    wchar_t _UNICODE 已定义。

    在Unix世界(特别是Bell实验室的plan9),开发人员决定更容易扩展Unix现有的东亚多字节字符支持来处理3字节字符,并创建了现在称为UTF-8的编码。近年来,类Unix系统已经使UTF-8成为大多数地区的默认编码。

    窗户理论上 扩展他们的ANSI支持以包括UTF-8,但是 they still haven't ,因为对字符的最大大小进行了硬编码假设。所以,在Windows上,你会被一个不支持UTF-8和C++运行库的OS支持,它不支持UTF-8。

    结果是:

    • UTF-8是Unix上最容易使用的编码。

    这给跨平台代码带来了听起来一样多的复杂性。如果你只是 选择一个Unicode编码 坚持下去。

    应该是哪种编码?

    看到了吗 UTF-8 or UTF-16 or UTF-32 or UCS-2

    总而言之:

    世界卫生组织

    依赖于区域设置 世界卫生组织 作为东亚编程遗产的编码。

    uint32_t 或等效的typedef来存储字符。或使用 世界卫生组织 __STDC_ISO_10646__ 定义和 第32页 .

    新的C++标准将有 char16_t char32_t ,这将有望消除如何表示UTF-16和UTF-32的混淆。

    是的Windows typedef 世界卫生组织 _UNICODE码 定义和

    my opinion , TCHAR 烧焦 与平台相关的缺点 世界卫生组织 . 避开它。

    字符编码是关于信息交换的。这就是“II”在ASCII中的含义。你的程序不是在真空中存在的。您必须读写文件,这些文件更有可能是用UTF-8编码的,而不是用UTF-16编码的。

    我的建议是 使用编码形式,使转换量最小化。

    这个程序应该能够使用

    最好让您的程序在内部完全使用Unicode,并且只处理读取遗留数据(或写入遗留数据,但是 只有 如果明确要求的话。)

        2
  •  2
  •   Loki Astari    15 年前

    你必须决定如何在内部表示文本。

    然后,无论何时读取任何输入,都必须将代码从输入格式转换为内部格式。然后从内部格式到输出格式就行了。如果您碰巧在内部和外部使用相同的格式,这将成为一个标识操作。


    UTF-16:被认为是全人类的救世主。
    但很快就被UTF-32取代了


    易于与UTF-8进行转换。
    非常庞大(每个字符占用4个字节)。

    大多数操作系统要么已经转换为UTF字符串表示形式,要么正朝着这个方向发展。因此,在内部使用像ISO-8859这样的onld obsolte格式仅仅意味着对操作系统的调用将导致额外的工作,因为字符串被转换成UTF。结果(对我来说)这似乎是浪费时间。

        3
  •  1
  •   Cratylus    15 年前

    您必须决定要使用哪种Unicode编码,例如UTF-8、ISO-8859-1等 然后,在所有的字符串操作中,C++中都应该考虑到这一点。例如,看一看w\u char和wstring。 在非Unicode环境中,我假设您的意思是输入变量将仅为ascii?

        4
  •  1
  •   karunski    15 年前

    “”的区域设置标识符(空字符串)指定特定于实现的默认区域设置。所以,如果将全局区域设置为 std::locale("") 然后,在理论上,您将获得一个基于环境的区域设置初始化的默认区域设置。这与标准c++提供的帮助差不多。

    这在Windows上有一些主要的限制,MSVC不提供任何带有UTF-8编码的std::locale。MacOSX除了与区域性无关的“C”语言环境外,不提供任何std::语言环境。

    在实践中,在应用程序内部的任何地方都可以标准化UTF-8编码的std::string。然后,在那些 具体的 在需要与操作系统交互的情况下,根据需要进行代码转换。例如,在unix上使用UTF-8编码的const char*来定义文件名,而在windows上使用UTF-16编码的wchar*来定义文件名。

        5
  •  1
  •   Matthieu M.    15 年前

    就我个人而言,我会走另一条路。

    不管您选择什么格式,它都应该支持Unicode,这是给定的。但是,您当然不必感到受限于使用现有编码。

    特定的编码意味着易于通信,但是由于Unix默认为UTF-8,Windows默认为UTF-16,因此不可能有通用编码。因此,我只建议使用您自己的内部表示,并根据您的目标操作系统应用适当的转换。这取决于到所需函数的公共接口和每个操作系统/编码的实现。

    另外请注意,不管您在哪个平台上,您都应该能够动态更改编码/解码(例如,可能会要求您在Unix上对特定文件使用UTF-32),这是不使用给定编码的另一个原因。

    总而言之:

    • ICU
    • 如果您自己实现它,并希望成为某种“标准”使用UTF-32(每点4字节)
    • 如果内存不足,则21位(<3字节)足以对所有现有点进行编码

    转换看似“计算机密集型”,但:

    • 你可以顺流做

    我的两个CT,就像他们说的:)

        6
  •  0
  •   Daniel Trebbien    15 年前

    typedef 和一些基于条件编译定义的宏。例如:

    #ifdef UNICODE
    #define mychar wchar_t
    #define s(a) L ## a
    typedef std::wstring mystringa;
    #else
    #define mychar char
    #define s(a) a
    typedef std::string mystringa;
    #endif
    typedef std::basic_string<mychar> mystringb;
    

    等等。然后使用字符串作为 s("foo") mystringa(s("foo"));