【问题标题】:C++ UNICODE and STLC++ UNICODE 和 STL
【发布时间】:2012-03-08 19:25:53
【问题描述】:

UNICODE 上的 Windows API 似乎很大,您在 Visual C++ 中创建了一个新项目,默认情况下将其设置为 UNICODE
而我想成为一名优秀的 Windows 程序员,我想使用UNICODE

问题在于 C++ 标准库和 STL(例如 std::stringstd::runtime_error)不能很好地与 UNICODE 字符串一起使用. 我只能将 std::stringchar* 传递给 std::runtime_error,而且我很确定 std::string i> 不支持UNICODE

所以我的问题是,我应该如何使用诸如 std::runtime_error 之类的东西?我应该将UNICODE 和普通ANSI 混合使用吗? (我认为这是一个坏主意......)
在我的整个项目中使用ANSI? (不喜欢......)还是什么?

【问题讨论】:

  • 它们是例外,你认为你需要将它们国际化并且真的需要它们的 unicode 支持吗?
  • 您可以在整个过程中主要使用std::wstringstd::runtime_error 是一个不幸的例外(没有双关语!)。
  • @Björn 相关但不重复。另一个问题的答案是关于使用char* 存储UTF-8。这在这里无济于事,因为 WinAPI 使用 wchar_t 和 UTF-16,因此无法调整答案。
  • 理想情况下,Windows 会更新为支持并默认开始使用 UTF-8 语言环境。

标签: c++ windows unicode stl c++-standard-library


【解决方案1】:

一般来说,您不应该混合使用这两种编码。然而,异常消息只是开发人员感兴趣的东西(例如在日志文件中),不应该向用户显示(但请查看 Jim 的评论以了解重要的警告)。

因此,如果您在整个面向用户的界面中使用 UNICODE 并在后台使用 std::exception 等来获取开发者消息,那么您是安全的。应该不需要在两者之间进行转换。

此外,在 C++ 中为 UNICODE 独立字符串定义 typedef 是一个好技巧:

typedef std::basic_string<TCHAR> tstring;

… 并类似地定义tcouttcin 等有条件的:

#ifdef UNICODE
    std::wostream& tcout = std::wcout;
    std::wostream& tcerr = std::wcerr;
    std::wostream& tclog = std::wclog;
    std::wistream& tcin = std::wcin;
#else
    std::ostream& tcout = std::cout;
    std::ostream& tcerr = std::cerr;
    std::ostream& tclog = std::clog;
    std::istream& tcin = std::cin;
#endif

【讨论】:

  • 我认为有一个论点是,对于像日志文件这样的情况,你应该使用 Unicode 字符串。日志文件经常将用户数据与系统数据混合在一起,并且用户数据很可能包含 Unicode 内容。你总是可以假设 ANSI 异常,但一个好的异常可能包括一个文件路径(比如说一个文件未找到异常),并且该路径可能包括 Unicode 字符)。
  • 为 typedef 技巧点赞。但是,如果我希望向用户显示错误消息以便他们报告/识别问题怎么办?编辑:Jim Lamb 说的差不多。
  • @Josh 不幸的是,这是您需要转换的少数情况之一,例如使用MultiByteToWideChar
【解决方案2】:

乔希,

请在此处查看我的答案:https://softwareengineering.stackexchange.com/questions/102205/should-utf-16-be-considered-harmful

越来越多的工程师认为 std::string 非常适合 Windows 上的 unicode,并且是更快编写可移植和 unicode 正确程序的正确方法。

【讨论】:

    【解决方案3】:

    看看 CodeProject 上的这篇(现在相当老的)文章:Upgrading an STL-based application to use Unicode。它涵盖了广泛使用 STL 时可能遇到的问题。它不应该那么糟糕,一般来说,使用宽字符串是值得的。

    【讨论】:

    • 嗯,这篇文章已经过时了。例如,它说wchar_tunsigned short 的typedef,这会导致过载问题。现代编译器并非如此。
    【解决方案4】:

    要使用 Windows Unicode API,只需使用宽字符串版本 - wstring 等。它对exception::what() 没有帮助,但如果你真的需要 Unicode,你可以使用 UTF-8 编码。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-02-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-10
      • 2010-09-28
      • 2018-10-10
      相关资源
      最近更新 更多