我想了解 char
和 wchar_t
之间的区别?我知道 wchar_t
使用更多字节,但我可以得到一个明确的例子来区分我何时使用 char
与 wchar_t
原文由 Ankit Goel 发布,翻译遵循 CC BY-SA 4.0 许可协议
我想了解 char
和 wchar_t
之间的区别?我知道 wchar_t
使用更多字节,但我可以得到一个明确的例子来区分我何时使用 char
与 wchar_t
原文由 Ankit Goel 发布,翻译遵循 CC BY-SA 4.0 许可协议
简短回答:
你不应该在现代 C++ 中使用 wchar_t
,除非与特定于操作系统的 API 交互(基本上使用 wchar_t
仅调用 Windows API 函数)。
长答案:
标准 C++ 库的设计意味着只有一种处理 Unicode 的方法——将 UTF-8 编码的字符串存储在 char 数组中,因为几乎所有函数都只存在于 char 变体中(想想 std::exception::what
)。
在 C++ 程序中,您有两个语言环境:
std::setlocale
std::locale::global
不幸的是,它们都没有定义打开文件的标准函数的行为(如 std::fopen
, std::fstream::open
等)。操作系统之间的行为不同:
在 Linux 上一切正常,因为每个人都使用基于 UTF-8 的语言环境,因此所有传递给 main
函数的用户输入和参数都将采用 UTF-8 编码。但是您可能仍需要将当前语言环境显式切换为 UTF-8 变体,因为默认情况下 C++ 程序开始使用默认 "C"
语言环境。此时,如果您只关心 Linux 而不需要支持 Windows,则可以使用 char 数组和 std::string
假设它是 UTF-8 序列并且一切都“正常工作”。
当您想要支持 Windows 时会出现问题,因为您总是有额外的第三种语言环境:为当前用户设置的一种,可以在“控制面板”中的某处进行配置。主要问题是该语言环境从来都不是 Unicode 语言环境,因此 不可能 使用 std::fopen(const char *)
和 std::fstream::open(const char *)
之类的函数来使用 Unicode 路径打开文件。在 Windows 上,您必须使用使用非标准 Windows 特定功能的自定义包装器,例如 _wfopen
, std::fstream::open(const wchar_t *)
在 Windows 上。您可以检查 Boost.Nowide(尚未包含在 Boost 中)以了解如何做到这一点: http ://cppcms.com/files/nowide/html/
使用 C++17,您可以使用 std::filesystem::path
以可移植的方式存储文件路径,但在 Windows 上仍然存在问题:
std::filesystem::path::path(const char *)
在 MSVC 上使用用户特定的语言环境,并且无法使其使用 UTF-8。函数 std::filesystem::u8string
应该用于从 UTF-8 字符串构造路径,但是很容易忘记这一点并改用隐式构造函数。std::error_category::message(int)
对于两个错误类别都使用用户特定的编码返回错误描述。所以我们在 Windows 上拥有的是:
main(int, char**)
的参数已损坏,不应使用。std::filesystem::path
部分损坏,切勿直接使用。std::generic_category
和 std::system_category
返回的错误类别已损坏,不应使用。如果您需要一个重要项目的长期解决方案,我建议:
std::generic_category
和 std::system_category
返回的标准错误类别,以便它们始终返回 UTF-8 编码的字符串。std::filesystem::path
以便新类在将路径转换为字符串并将字符串转换为路径时始终使用 UTF-8。std::filesystem
的所有必需函数,以便它们使用您的路径包装器和错误类别。不幸的是,这不会解决与文件一起使用的其他库的问题,但无论如何很多都被破坏了(不支持 unicode)。
您可以查看此链接以获得进一步的解释: http ://utf8everywhere.org/
原文由 user1143634 发布,翻译遵循 CC BY-SA 4.0 许可协议
3 回答1.3k 阅读✓ 已解决
1 回答1.1k 阅读✓ 已解决
4 回答846 阅读
1 回答922 阅读
1 回答957 阅读
1 回答723 阅读
1 回答823 阅读
从根本上说,当编码的符号多于
char
可以包含的符号时,使用wchar_t
。背景
char
类型有足够的容量容纳 ASCII 字符集中的任何字符(编码)。问题是许多语言需要比 ASCII 更多的编码。因此,需要更多而不是 127 种可能的编码。有些语言有超过 256 种可能的编码。
char
类型不保证范围大于 256。因此需要新的数据类型。wchar_t
又名宽字符,为编码提供了更多空间。概括
当编码范围为 256 或更少时使用
char
数据类型,例如 ASCII。当您需要超过 256 的容量时,请使用wchar_t
。首选 Unicode 来处理大型字符集(例如表情符号)。