c++ - 使用 Visual Studio 2019 编译 Unicode
问题描述
我尝试在 VS2019 上编译这个 C++17 代码:
int main() {
if(!testCodepointEncode(U'\u221A', '\xFB') ||
!testCodepointEncode(U'\u0040', '\x40') ||
!testCodepointEncode(U'\u03A3', '\xE4') ||
!testCodepointEncode(U'', '\xFE')) {
return 1;
}
// Test 1 byte
if(!testEncode("\u0040", "\x40")) {
return 2;
}
// Test 2 byte
if(!testEncode("\u03A3", "\xE4")) {
return 3;
}
// Test 3 byte
if(!testEncode("\u2502", "\xB3")) {
return 4;
}
// Test 4 byte
if(!testEncode("", "\xFE")) {
return 5;
}
if(!testArray("F ⌠ Z", "\x46\x20\xF4\x20\x5A")) {
return 6;
}
if(!testView("F ⌠ Z", "\x46\x20\xF4\x20\x5A")) {
return 7;
}
return 0;
}
它可以在 Linux 上与 gcc 和 clang 一起编译并正常工作,但 MSVC 抱怨:
UNICODE_TEST.CPP(65,27):错误 C2015:常量中的字符太多 UNICODE_TEST.CPP(75,18):警告 C4566:由通用字符名称“\u03A3”表示的字符无法在当前代码页中表示 (1252) UNICODE_TEST.CPP(80,18):警告 C4566:universal-character-name '\u2502' 表示的字符无法在当前代码页中表示 (1252)
我尝试将当前代码页设置为 UTF-8,但错误仍然存在。
应该如何在 Windows 上编译此代码?
解决方案
仔细看看你在这条线上做了什么:
if(!testEncode("\u03A3", "\xE4")) {
引用字符串文字:
"\u03a3"
您试图在 8 位 (char*) 字符串文字中表达 UTF-16 字符。那是行不通的。这相当于这样做:
char sz[2] = {0};
sz[0] = (char)(0x03a3);
并期望sz[0]
保留原始的 UTF-16 字符。这就是编译器警告您的内容。
如果要在字符串文字中表示 16 位 unicode 字符,请使用宽字符串。如下带有L
前缀:
L"\u03a3"
上面是一个字符串文字,它包含一个信号宽字符:L"Σ"
如果我们真的想要挂起,我们可以这样说来可移植地表达一个 UTF-16 字符串,使用u
前缀:
u"\u03a3"
但是在 Windows 上 wchar_t 是 16 位的,所以这并不重要。
您可能需要修复您的testEncode
函数以期望 aconst wchar_t*
而不是const char*
参数。(老实说,我不确定你的test*
函数在做什么,但如果目标是确认 UTF8 到 UTF16 的转换,你的一些参数看起来很可疑)
如果你想在代码中表达一个 UTF-8 字符串,你可以这样说:
"\xCE\xA3"
以上是将 sigmaΣ
字符的 UTF-8 表示为 UTF-8 字符串
推荐阅读
- python - 为什么这些自定义函数在 Python 中打印不同的值?
- javascript - 将参数传递给 JSON 对象中的函数
- jquery - 通过ajax将带有图像和json的Formdata发送到服务器端
- css - 将图像大小调整为 CSS 网格,同时在悬停时进行图像替换
- javascript - 从 JavaScript 中的 2 个不同来源增加一个值
- tomcat - 如何让 Tomcat 接受端口 8443 上的 SSL 连接?
- javascript - 在末尾隐藏一个div
- reactjs - 测试对儿童进行操作的效用函数
- jquery - jQuery / 选择选项元素
- java - 我试图在 4 名玩家之间平均处理一副 52 张扑克牌,这意味着他们每人将有 13 张牌。每张只能发牌 4 张