c ++字符串文字仍然令人困惑

use*_*715 9 c++ unicode

我一直在阅读一些关于Unicode的文章,并意识到我仍然对这件事做些什么感到困惑.

作为Windows平台上的c ++程序员,给予我的学科与任何教师大致相同:始终使用Unicode字符集; 如果可能的话,将其模板化或使用TCHAR; 喜欢wchar_t,std :: wstring over char,std :: string.

#include <tchar.h>
#include <string>
typedef std::basic_string<TCHAR> tstring;
 // ...
static const char* const s_hello = "??"; // bad
static const wchar_t* const s_wchar_hello = L"??" // better
static LPCTSTR s_tchar_hello = TEXT("??") // even better
static const tstring s_tstring_hello( TEXT("??") ); // best
Run Code Online (Sandbox Code Playgroud)

不知怎的,我搞砸了,我引导自己相信如果我说"某事",那就意味着它是ASCII格式的,如果我说L"某事"就是Unicode.然后我读到了这个:

类型wchar_t是一种不同的类型,其值可以表示支持的语言环境(22.3.1)中指定的最大扩展字符集的所有成员的不同代码.类型wchar_t应具有与其他整数类型之一相同的大小,符号和对齐要求(3.11),称为其基础类型.类型char16_t和char32_t分别表示与uint_least16_t和uint_least32_t相同的大小,符号和对齐的不同类型,称为基础类型.

所以呢?如果我的语言环境从代码页949开始,那么wchar_t的扩展是从949 + 2 ^(sizeof(wchar_t)*8)?它说话的方式听起来像'我不在乎你的c ++实现是使用UTF编码还是什么'.

至少,我可以理解一切都取决于应用程序所在的语言环境.因此我测试了:

#define TEST_OSTREAM_PRINT(x) \
std::cout << "----" << std::endl; \
std::cout << "cout : " << x << std::endl; \
std::wcout << "wcout : " << L##x << std::endl;

int main()
{
    std::ostream& os = std::cout;

    std::cout << " * Info : " << std::endl
              << "     sizeof(char) : " << sizeof(char) << std::endl
              << "     sizeof(wchar_t) : " << sizeof(wchar_t) << std::endl
              << "     littel endian? : " << IsLittelEndian() << std::endl;
    std::cout << " - LC_ALL: " << setlocale(LC_ALL, NULL) << std::endl;
    std::cout << " - LC_CTYPE: " << setlocale(LC_CTYPE, NULL) << std::endl;

    TEST_OSTREAM_PRINT("??");
    TEST_OSTREAM_PRINT("?????");
    TEST_OSTREAM_PRINT("??");
    TEST_OSTREAM_PRINT("resume");
    TEST_OSTREAM_PRINT("résumé");

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

然后输出是:

Info
 sizeof(char) = 1
 sizeof(wchar_t) = 2
 LC_ALL = C
 LC_CTYPE = C
----
cout : ??
wcout : ----
cout : ?????
wcout : ----
cout : ??
wcout : ----
cout : resume
wcout : resume
----
cout : r?sum?
wcout : r?um
Run Code Online (Sandbox Code Playgroud)

韩语语言环境的另一个输出:

Info
 sizeof(char) = 1
 sizeof(wchar_t) = 2
 LC_ALL = Korean_Korea.949
 LC_CTYPE = Korean_Korea.949
----
cout : ??
wcout : ??
----
cout : ?????
wcout : ?????
----
cout : ??
wcout : ----
cout : resume
wcout : resume
----
cout : r?sum?
wcout : resume
Run Code Online (Sandbox Code Playgroud)

另一个输出:

Info
 sizeof(char) = 1
 sizeof(wchar_t) = 2
 LC_ALL = fr-FR
 LC_CTYPE = fr-FR
----
cout : CU·I
wcout : ----
cout : ªªªIªeª|¡?
wcout : ----
cout : ?u¿
wcout : ----
cout : resume
wcout : resume
----
cout : r?sum?
wcout : resume
Run Code Online (Sandbox Code Playgroud)

结果如果我没有给出正确的语言环境,应用程序无法处理某些范围的字符,无论我使用char还是wchar_t.这不仅仅是问题.Visual studio发出警告:

warning C4566: character represented by universal-character-name '\u4F60' cannot be represented in the current code page (949)
Run Code Online (Sandbox Code Playgroud)

我不确定这是否描述了我得到的输出或其他东西.

题.什么是最佳实践以及为什么?如何使应用程序平台/实现/国家独立?源上字符串文字究竟发生了什么?应用程序如何解释字符串值?

ixS*_*Sci 3

C++ 没有正常的 Unicode 支持。如果不使用第 3 方库,您就无法用 C++ 编写正常的全球化应用程序。阅读这个富有洞察力的答案。如果您确实需要编写使用 Unicode 的应用程序,我会查看ICU库。