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

在C++中创建支持Unicode和ASCII的库的最佳实践是什么?

  •  4
  • bsruth  · 技术社区  · 15 年前

    我正在编写一些库,这些库将在内部和客户中使用,我想知道支持unicode和ascii的最佳方法是什么。看起来Microsoft(在MFC库中)同时编写Unicode和ASCII类,并使用宏在头文件中执行类似的操作:

    #ifdef _UNICODE
    #define CString CStringW
    #else
    #define CString CStringA
    #endif
    

    虽然我不是宏的超级粉丝,但它确实起到了作用。如果我使用stl编写库,那么编写包含以下内容的头是否有意义:

    #ifdef _UNICODE
    #define GetLastErrorString GetLastErrorStringW
    #else
    #define GetLastErrorString GetLastErrorStringA
    #endif
    
    std::string GetLastErrorStringA();
    std::wstring GetLastErrorStringW();
    

    或者我应该发布单独的库,一个用于ascii,一个用于unicode?

    只是想知道人们认为在这种情况下最好做什么。

    更新:解决一些评论和问题:

    • 这些将是C++类库。
    • 我相信我需要使用utf-16编码,因为我想支持亚洲字符集。
    • 我实现unicode的原因有两个:1)所有新的sdk都支持unicode,我不相信将来的sdk或第三方库将来会支持单独的ascii版本。2)虽然我们不会完全国际化我们的应用程序,但如果我们能够处理用户输入(如名称)和从包含亚洲字符的路径加载的文件,那将是很好的。
    4 回复  |  直到 15 年前
        1
  •  4
  •   Michael    15 年前

    我会在内部使库完全Unicode。然后,一组C++适配器类将存在于ASCII中,即Tube到Unicode实现。

        2
  •  1
  •   StackedCrooked    15 年前

    如果将第一个字符串转换为UTF-8,则可以将Unicode字符串存储STD::

    当与utf-16调用(如windows api)交互时,只需要wstring。如果是这种情况,您可以在需要的地方将字符串本地转换为wstring。这可能有点累赘,但也没那么糟。

        3
  •  0
  •   Community CDub    7 年前

    这个问题有点不准确,但是…

    首先你必须精确编码。unicode只是字符的一种表示(每个字符都与一个码位相关联),在应用程序中处理unicode时,必须选择如何表示码位。如果你可以使用UTF-8,你就不用担心宽字符,你可以把数据存储在一个普通的STD::String:)中。

    那么你必须精确地说明你的问题:

    • 是否支持Unicode和ASCII格式的条目?
    • 或者你说的是产出?
    • 不管怎样,你可以使用STD::LoaLaC知道应该输出哪个编码?

    我正在研究国际化的应用程序(一个网站,带有一个C++后端…),我们只需在内部使用STD::String。ascii或utf-8格式的输出取决于翻译文件,但数据表示形式没有任何变化(除了计算字符,请参见 my post 关于这个话题)。

    真的,我绝对不喜欢宏,因为utf-8本来是要与ascii兼容的,如果你能选择自己的编码,你就得救了!

        4
  •  0
  •   WeBMartians    15 年前

    你问的是代码的“可理解性”,而不是使用ascii、utf-8、16或32位字符。

    如果是这样的话,我更喜欢使代码块尽可能大:这样就可以使用“gate”(unicode符号常量)来选择单独的文件,或者至少选择大块代码。在一个语句中,每隔一行或几行,或天不允许,就改变其位置的代码是很难理解的。

    我建议不要用这个门来选择包含单独的文件

    #ifdef _UNICODE
    #include "myUniLib.h"
    #else
    #include "myASCIILib.h"
    #endif
    

    因此可能需要两个甚至三个文件(unicode文件、646us(ascii)文件,以及可能包含上述代码的nexus文件)。这是丢失某些内容并导致生成失败的可能性的三倍。

    相反,使用文件中的gate来选择大块代码:

    #ifdef _UNICODE
       ...lotsa code...
    #else
       ...lotsa code...
    #endif
    

    好吧,假设你在做相反的事情:想知道char与char(utf-8)与w与a。你想成为多普遍的人?您所提到的cstrings仅适用于windows世界。如果你想与mac和unix(好的,linux)兼容,那你就要经历一段艰难的旅程。

    顺便说一下,ascii是…不是…一个公认的标准。有ascii,然后有…ASCII如果您指的是unix旧时代的7位“标准”,那么我找到的最接近的是iso-646us。Unicode等价物是ISO-10646。

    有些人很幸运地将字符编码为url:ascii字母和数字以及百分比符号。虽然您必须一直进行编码和解码,但存储确实是可预测的。有点奇怪,是的,但绝对是创新的。

    有一些语言上的陷阱。例如,不要依赖case来实现双向(这里我不知道正确的单词)。在Deutsch中,小写在转换为大写时变为ss。然而,当小写时,ss变形为ss,而不是_。土耳其语也有相似之处。在设计应用程序时,不要认为案例翻译可以帮助您。

    另外,请记住,不同语言的语法顺序是不同的。“你好,吉姆!星期一过得怎么样?”最后会说“你好!你的,星期一,一切顺利,吉姆?”

    STD::CIN:L&&L.and STD::COUT和GT;GT;它会诱使您以这样一种方式嵌入消息生成器,使得本地化它们变得非常困难。

    你问的问题是对的。你前面有一场冒险!最好!