char vs wchar_t何时使用哪种数据类型

Ank*_*oel 13 c++

我想了解的区别charwchar_t?我理解wchar_t使用更多的字节但是我可以得到一个明确的例子来区分我何时使用charvswchar_t

Tho*_*ews 12

从根本上说,wchar_t当编码具有比char可以包含的符号更多的符号时使用.

背景
char类型具有足够的容量来保持在ASCII字符集的任何字符(编码).

问题是许多语言需要比ASCII帐户更多的编码.因此,代替127种可能的编码,需要更多.有些语言有超过256种可能的编码.甲char类型并不保证的范围大于256因此,一个新的数据类型是必需的大.

wchar_t,又名宽字符,提供了编码更大的空间.

摘要当编码范围为256或更小时
使用char数据类型,例如ASCII.wchar_t当您需要超过256的容量时使用.

首选Unicode来处理大字符集(例如emojis).

  • 使用以下语句找出:`std :: cout << sizeof(wchar_t)<<“ \ n”;`。如果打印少于4,则您的答案为“否”。 (2认同)
  • 使用Unicode的首选方法是使用[`char16_t`和`char32_t`](http://en.cppreference.com/w/cpp/language/types#Character_types),因为它们具有已知的大小和范围. (2认同)

o11*_*11c 11

切勿使用wchar_t.

如果可能,使用(某种数组)char,例如std::string,并确保它以UTF-8编码.

如果必须与不使用UTF-8的API进行交互,请使用char16_tchar32_t.否则不要使用它们; 它们只提供虚幻的优势并鼓励错误的代码.

请注意,在很多情况下,需要多个char32_t表示单个用户可见字符的情况.OTOH,使用UTF-8 char强迫您尽早处理可变宽度.

  • 某些Windows API需要`wchar_t`,但是在Windows上您知道`wchar_t`是16位并且具有一定的稳定性。而且char32_t可以表示所有Unicode字符,这可能只是用户认为的字符的一个子集,但有时却很有用。我同意`char16_t`可能仅在与需要UTF-16的系统接口时才有用。 (2认同)

Sta*_*irl 9

简短的anwser:

wchar_t除非与特定于操作系统的API交互(基本上wchar_t只用于调用Windows API函数),否则永远不要在现代C++中使用.

答案很长:

标准C++库的设计意味着只有一种方法可以处理Unicode - 通过在char数组中存储UTF-8编码的字符串,因为几乎所有函数都只存在于char变体中(想想std::exception::what).

在C++程序中,您有两种语言环境: - 标准C库语言环境设置std::setlocale - 标准C++库语言环境设置std::locale::global

不幸的是,他们没有定义的打开文件(如标准功能的行为std::fopen,std::fstream::open等等).操作系统之间的行为不同: - Linux编码不可知,因此这些函数只是将char字符串传递给底层系统调用 - 在Windows系统调用之前,使用用户特定的语言环境将Windows字符串转换为宽字符串

一切都通常在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**)被破坏,永远不应该使用.
  • 以*A和宏结尾的WinAPI函数被破坏,永远不应该使用.
  • std::filesystem::path 部分损坏,不应直接使用.
  • 错误类型的返回std::generic_categorystd::system_category破裂,绝不应该被使用.

如果你需要一个非平凡的项目的长期解决方案,我会建议:

  • 使用Boost.Nowide或直接实现类似的功能 - 这个固定的破坏标准库.
  • 重新实现返回的标准错误类别std::generic_category,std::system_category以便它们始终返回UTF-8编码的字符串.
  • 包装,std::filesystem::path以便在将路径转换为字符串并将字符串转换为路径时,新类始终使用UTF-8.
  • 包装所有必需的函数,std::filesystem以便它们使用您的路径包装器和您的错误类别.

不幸的是,这不会解决其他使用文件的库的问题,但是其中99%都会被破坏(不支持unicode).

这就是C++程序员的生活.Microsoft可以通过允许我们将Windows运行时切换到基于UTF-8的语言环境来解决这个问题,但由于向后兼容性,它们不会.

您可以查看此链接以获得进一步说明:http://utf8everywhere.org/